Spark自由操作不适用于自定义类型

时间:2015-08-10 13:47:33

标签: scala apache-spark distinct

我在Scala中使用Spark,并且我正在尝试distinct内置自定义对象元素的RDD。

找不到明确的操作,"删除"操作后的副本和RDD仍然与以前相同。 我不明白为什么会这样。在我尝试在原始类型的RDD上执行distinct之后,我得到了一个提示(并且它有效)。所以我试图在我的自定义对象中扩展Ordered,但没有发生新的事情。

按照我的测试代码。

class AA (val a: Int, val b: Int) extends Ordered[AA] {

    override def toString = "("+a+","+b+")"

    override def equals(t : Any) = t match {
       case that: AA => this.a == that.a & this.b == that.b
       case _ => super.equals(t)
    }

    override def compare(that: AA): Int = { this.b compare that.b }
}

distinct操作在这里:

val par = sc.parallelize[AA](List(new AA(1,2), new AA(2,3), new AA(2,1), new AA(3,2), new AA(3,2)))

println("Count Before: "+par.count())                 // 5
println("Count After: "+par.distinct().count())       // still 5

我甚至尝试使用reduceByKey()aggregateByKey()使用不同的执行流来计算不同,但也没有运气。

这里发生了什么?

提前感谢大家。

3 个答案:

答案 0 :(得分:6)

您还需要提供hashCode

override def hashCode = (a, b).hashCode

或者,您可以使用案例类

免费获得equalshashCode

答案 1 :(得分:0)

您可以使用case classhashCode附带的equals,以便distinct可以立即使用:

case class AA (val a: Int, val b: Int) {
  override def toString = "("+a+","+b+")"
}

请注意,它可能会在Spark REPL中出错:https://issues.apache.org/jira/browse/SPARK-2620但它会在实际执行您的工作时起作用。

答案 2 :(得分:0)

当我运行您的代码时,我得到java.io.NotSerializableException

您不需要实现Ordering并覆盖这些方法,只需使用案例类:

import org.apache.spark.{SparkContext, SparkConf}

case class AA (val a: Int, val b: Int)

val conf = new SparkConf().setMaster("local").setAppName("example")
val sc = new SparkContext(conf)

val par = sc.parallelize[AA](List(AA(1, 2), AA(2, 3), AA(2, 1), AA(3, 2), AA(3, 2)))

println("Count Before: " + par.count()) // 5
println("Count After: " + par.distinct().count()) // 4