【问题标题】:scala map over rdd ERROR java.lang.NullPointerExceptionrdd上的scala映射错误java.lang.NullPointerException
【发布时间】:2020-09-28 09:23:43
【问题描述】:

当我尝试映射从 HDFS 读取的 rdds 时遇到一个奇怪的错误,这是我的代码(简化)。

我尝试将 RDD 放入 Scala Map,然后选择某些键值来写入 HDFS。我在下面运行了这段代码,但是每次运行到“map over rdd”过程(我在下面做了评论),我遇到了 NPE 错误,太奇怪了!

我无法解决这个问题。我以一种笨拙而丑陋的方式重写了我的代码以使其工作,但我仍然想知道为什么“映射超过 rdd”很重要!!!

顺便说一句: 我使用的所有键都存在于 scala 映射中,并且没有空值。我删除了“map over rdd”进程并将键值写入字符串以使我的代码以另一种方式工作,但只是想知道为什么会发生这个奇怪的问题......T_T

val featureRdd = hdfsRDD
  .flatMap { item =>
    val result = new ArrayBuffer[String]()
    val itemInfo = collection.mutable.Map[String, String]()

    // x below is a string tuple: (s1, s2, s3)
    item._2.asScala.foreach(x => {
      itemInfo.put(x._2, x._3)
    })

    val f1 = itemInfo.getOrElse("f1", "")
    val f2 = itemInfo.getOrElse("f2", "")
    if (f1.equals("true") && f2.nonEmpty) {
      val c1 = itemInfo.getOrElse("c1", "0")
      val c2 = itemInfo.getOrElse("c2", "0")

      val featureInfo = collection.mutable.Map[String, String]()
      featureInfo.put("c1", c1)
      featureInfo.put("c2", c2)

      // Every time I add this map code, I will get NPE ERROR
      // And I'm sure this is no null values because I filter all null values ahead of time
      featureInfo.map(item => {
        val featureName = item._1
        val featureValue = item._2
        result += List(featureName, featureValue).mkString(",")
      })
      result
    } else {
      null
    }
  }.filter(_!=null)

【问题讨论】:

  • 为什么你甚至返回 null 呢?你在flatMap,只返回一个空列表
  • 是的,但这是一个不会使代码失败的细节:(
  • 你确定不会吗?在flatMap 中返回null 势必会带来麻烦。您可能还想发布有效的代码以及异常的堆栈跟踪。
  • 其实你们是完全正确的!代码所有者,不是我,写了代码放到网上,现在想知道这段代码是运行了很久还是失败了很久:-P

标签: java scala apache-spark rdd


【解决方案1】:

这显然是由于在您的flatMap 中返回了nullRDD.flatMap 推迟到 Iterator.flatMap,看看这个:

println(List(List(1), null).iterator.flatMap(identity).toList) // throws NPE
Exception in thread "main" java.lang.NullPointerException
    at scala.collection.Iterator$$anon$11.nextCur(Iterator.scala:480)
    at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:486)
    at scala.collection.Iterator.foreach(Iterator.scala:937)
    at scala.collection.Iterator.foreach$(Iterator.scala:937)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1425)
    at scala.collection.generic.Growable.$plus$plus$eq(Growable.scala:58)
    at scala.collection.generic.Growable.$plus$plus$eq$(Growable.scala:49)
    at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:185)
    at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:43)
    at scala.collection.TraversableOnce.to(TraversableOnce.scala:309)
    at scala.collection.TraversableOnce.to$(TraversableOnce.scala:307)
    at scala.collection.AbstractIterator.to(Iterator.scala:1425)
    at scala.collection.TraversableOnce.toList(TraversableOnce.scala:293)
    at scala.collection.TraversableOnce.toList$(TraversableOnce.scala:293)
    at scala.collection.AbstractIterator.toList(Iterator.scala:1425)
    at com.dici.collection.ScalaArrayUtils$.main(ScalaArrayUtils.scala:22)
    at com.dici.collection.ScalaArrayUtils.main(ScalaArrayUtils.scala)

更具体地说,这是我希望您的 NPE 来自的地方:link。 只需删除此 null return 并将其替换为空的迭代即可。

【讨论】:

  • 非常感谢 Dici!这个答案很有帮助。我从来不知道 flatMap 的特点 :-P 对不起,我不能投票这个答案,因为这个帐户是一个新帐户 :-(
  • 哈哈我明白了,不用担心
猜你喜欢
  • 2021-12-02
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 2017-09-29
  • 2020-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多