一、背景
1、在scala-2.10.x版本種,case class的元素超過22個以後即會編譯報錯
2、有些業務場景下,需要超過22個元素的值
我們項目當中日誌一共有105個字段,在對原始日誌進行處理轉換成parquet文件的過程中,我們使用的方法是定義一個case class類,將這105個字段封裝到這個對象裏面,基於這種方式構建的DataFrame。結果運行的時候報錯了,之後我們查閱官網,發現在scala 2.10版本中case class一共只支持22個字段,如果超過了就會報錯,然後官網也給了我們解決方法,就是自定義一個類實現product特質,這樣就能解決這個問題
二、如何解決
1、Scala提供瞭解決方案,即使用類實現Product特質
package com.ngaa.scala /**
* @author Created by yangjf on 20180712.
* Update date:
* Time: 15:43
* Project: dev-spark01-examples
* Package: com.ngaa.scala
* Describe : Scala構建超過22個元素的class
* API參考:
* https://www.scala-lang.org/api/current/scala/Product.html
* 學習參考:
* https://www.artima.com/pins1ed/
*
*/
object More22Elements { def main(args: Array[String]) { val student = new Student(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27) /* 獲取其中一個元素 */
println(student.productElement(1).toString) /* 是否包含元素:23 */
println(student.canEqual(23)) /* 遍歷元素 */
student.productIterator.foreach(println) /* toString方法 */
println(student.productPrefix) println(student.equals(student)) } } /** Student類中有大於22個元素的實現 */
class Student(one: Int, two: Int, three: Int, four: Int, five: Int
, six: Int, seven: Int, eight: Int, nine: Int, ten: Int, eleven: Int, twelve: Int
, thirteen: Int, fourteen: Int, fifteen: Int, sixteen: Int
, seventeen: Int, eighteen: Int, nineteen: Int, twenty: Int, first: Int, second: Int
,third:Int, fourth: Int, fifth: Int, sixth: Int, seventh: Int) extends Product { val arrays = Array(one, two, three, four, five , six, seven, eight, nine, ten, eleven, twelve , thirteen, fourteen, fifteen, sixteen , seventeen, eighteen, nineteen, twenty, first, second, third , fourth, fifth, sixth, seventh) /**
*
* 自定義比較:是否包含這個元素
*
* @param that 輸入的元素
* @return 是否包含,true代表包含
*/
override def canEqual(that: Any): Boolean = arrays.contains(that) /**
*
* 獲取迭代器
*
* @return 迭代
*/
override def productIterator: Iterator[Int] = new scala.collection.Iterator[Int] { private var c: Int = 0
private val cMax = productArity def hasNext = c < cMax
def next() = { val result = productElement(c) c += 1
result } }
/**
*
* 根據下標獲取元素
*
* @param n 下標
* @return 元素
*/
override def productElement(n: Int): Int = arrays(n)
/**
*
* 元素個數
*
* @return 元素個數
*/
override def productArity: Int = arrays.length
/**
*
* 類似toString方法
*
* @return 元素鏈接字符串
*/
override def productPrefix = arrays.mkString("\t")
}
2、升級scala版本,2.11版本之後是直接可以用的。