在Spark中用作HashMap键时,Scala case类对象'key not found'

时间:2017-01-11 20:38:55

标签: scala apache-spark hashmap case-class databricks

我正在尝试通过Spark 2.0中的函数访问HashMap,但如果我并行化List,它就会失败。如果我不这样做,它就可以工作,如果我不使用Case Class,它就可以工作。

以下是我正在尝试做的一些示例代码:

case class TestData(val s: String)

def testKey(testData: TestData) {
  println(f"Current Map: $myMap")
  println(f"Key sent into function: $testData")
  println("Key isn't found in Map:")
  println(myMap(testData)) // fails here
}

val myList = sc.parallelize(List(TestData("foo")))
val myMap = Map(TestData("foo") -> "bar")
myList.collect.foreach(testKey) // collect to see println

这是确切的输出:

Current Map: Map(TestData(foo) -> bar)
Key sent into function: TestData(foo)
Key isn't found in Map:
java.util.NoSuchElementException: key not found: TestData(foo)

上面的代码与我正在尝试的类似,除了case类更复杂并且HashMap将Lists作为值。同样在上面的示例中,我使用'collect'以便输出print语句。样本仍然提供相同的错误,没有收集,但没有打印。

hashCodes已经匹配,但我尝试覆盖case类的equals和hashCode,同样的问题。

这是使用Databricks,所以我不相信我可以访问REPL或spark-submit。

2 个答案:

答案 0 :(得分:0)

感谢评论指出the similar question,这引发了Spark问题,这导致我为我的案例提供了这个解决方案:

grep

覆盖equals以包含isInstanceOf可以解决问题。它可能不是最好的解决方案,但它绝对是最简单的解决方法。

答案 1 :(得分:0)

你的逻辑是循环的&错误。您正在将相同的RDD传递给Map&用TestData调用。更新它以使其顺序如下:

case class TestData(val s: String)

def testKey(testData: TestData) {
  val myMap = Map(testData -> "bar")
  println(f"Current Map: $myMap")
  println(f"Key sent into function: $testData")
  println("Key isn't found in Map:")
  println(myMap(testData)) // fails here
}

val myList = sc.parallelize(List(TestData("foo")))
myList.collect.foreach(testKey)

它的输出是:

Current Map: Map(TestData(foo) -> bar)
Key sent into function: TestData(foo)
Key isn't found in Map:
bar

我希望这是你所期待的......