我在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()
使用不同的执行流来计算不同,但也没有运气。
这里发生了什么?
提前感谢大家。
答案 0 :(得分:6)
您还需要提供hashCode
override def hashCode = (a, b).hashCode
或者,您可以使用案例类
免费获得equals
和hashCode
答案 1 :(得分:0)
您可以使用case class
和hashCode
附带的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