Scala 无法运行读取元组RDD并返回元组RDD的spark map函数

Scala 无法运行读取元组RDD并返回元组RDD的spark map函数,scala,apache-spark,Scala,Apache Spark,我需要从另一个成对的RDD生成一个成对的RDD。基本上,我正在尝试编写一个map函数,它可以执行以下操作 RDD[Polygon,HashSet[Point]] => RDD[Polygon,Integer] 以下是我编写的代码: Scala函数,它在HashSet上迭代并从“Point”对象中添加一个值 在成对RDD上应用该函数会引发错误: scala> val mappedJoinResult = joinResult.map((t: Tuple2[Polygon,HashSe

我需要从另一个成对的RDD生成一个成对的RDD。基本上,我正在尝试编写一个map函数,它可以执行以下操作

RDD[Polygon,HashSet[Point]] => RDD[Polygon,Integer]
以下是我编写的代码:

Scala函数,它在HashSet上迭代并从“Point”对象中添加一个值

在成对RDD上应用该函数会引发错误:

scala> val mappedJoinResult = joinResult.map((t: Tuple2[Polygon,HashSet[Point]]) => outCountPerCell(t))
<console>:82: error: type mismatch;
found   : ((com.vividsolutions.jts.geom.Polygon, java.util.HashSet[com.vividsolutions.jts.geom.Point])) => (com.vividsolutions.jts.geom.Polygon, Integer)
required: org.apache.spark.api.java.function.Function[(com.vividsolutions.jts.geom.Polygon, java.util.HashSet[com.vividsolutions.jts.geom.Point]),?]
       val mappedJoinResult = joinResult.map((t: Tuple2[Polygon,HashSet[Point]]) => outCountPerCell(t))
scala>val-mappedJoinResult=joinResult.map((t:Tuple2[Polygon,HashSet[Point]])=>outCountPerCell(t))
:82:错误:类型不匹配;
建立   : ((com.livitsolutions.jts.geom.Polygon,java.util.HashSet[com.livitsolutions.jts.geom.Point])=>(com.livitsolutions.jts.geom.Polygon,整数)
必需:org.apache.spark.api.java.function.function[(com.livitsolutions.jts.geom.Polygon,java.util.HashSet[com.livitsolutions.jts.geom.Point]),?]
       val mappedJoinResult=joinResult.map((t:Tuple2[Polygon,HashSet[Point]])=>outCountPerCell(t))

有人可以看看我缺少了什么,或者分享一下在map()操作中使用自定义函数的任何示例代码。

这里的问题是,
joinResult
是来自Java API的
JavaPairRDD
。此数据结构的
映射
需要Java类型的lambda(
函数
),它与Scala lambda不可互换(至少很少)

因此有两种解决方案:尝试将给定的方法转换为Java
函数
,以传递给
映射
,或者按照开发人员的意图使用Scala RDD:

设置虚拟数据 在这里,我创建了一些替代类,并制作了一个Java RDD,其结构与OP的类似:

scala> case class Polygon(name: String)
defined class Polygon

scala> case class Point(ordinate: Int)
defined class Point

scala> :pa
// Entering paste mode (ctrl-D to finish)

/* More idiomatic method */
def outCountPerCell( jr: (Polygon,java.util.HashSet[Point])) : (Polygon, Integer) =
{
    val count = jr._2.asScala.map(_.ordinate).sum
    (jr._1, count)
}

// Exiting paste mode, now interpreting.

outCountPerCell: (jr: (Polygon, java.util.HashSet[Point]))(Polygon, Integer)

scala> val hs = new java.util.HashSet[Point]()
hs: java.util.HashSet[Point] = []

scala> hs.add(Point(2))
res13: Boolean = true

scala> hs.add(Point(3))
res14: Boolean = true

scala> val javaRDD = new JavaPairRDD(sc.parallelize(Seq((Polygon("a"), hs))))
javaRDD: org.apache.spark.api.java.JavaPairRDD[Polygon,java.util.HashSet[Point]] = org.apache.spark.api.java.JavaPairRDD@14fc37a
使用Scala RDD 通过使用
.RDD
,可以从Java RDD检索底层Scala RDD:

scala> javaRDD.rdd.map(outCountPerCell).foreach(println)
(Polygon(a),5)
更好的方法是将
mapValues
与Scala RDD结合使用 由于只有元组的第二部分在更改,因此可以使用
.mapValues
干净地解决此问题:

scala> javaRDD.rdd.mapValues(_.asScala.map(_.ordinate).sum).foreach(println)
(Polygon(a),5)

这里的问题是
joinResult
是来自JavaAPI的
JavaPairRDD
。此数据结构的
映射
需要Java类型的lambda(
函数
),它与Scala lambda不可互换(至少很少)

因此有两种解决方案:尝试将给定的方法转换为Java
函数
,以传递给
映射
,或者按照开发人员的意图使用Scala RDD:

设置虚拟数据 在这里,我创建了一些替代类,并制作了一个Java RDD,其结构与OP的类似:

scala> case class Polygon(name: String)
defined class Polygon

scala> case class Point(ordinate: Int)
defined class Point

scala> :pa
// Entering paste mode (ctrl-D to finish)

/* More idiomatic method */
def outCountPerCell( jr: (Polygon,java.util.HashSet[Point])) : (Polygon, Integer) =
{
    val count = jr._2.asScala.map(_.ordinate).sum
    (jr._1, count)
}

// Exiting paste mode, now interpreting.

outCountPerCell: (jr: (Polygon, java.util.HashSet[Point]))(Polygon, Integer)

scala> val hs = new java.util.HashSet[Point]()
hs: java.util.HashSet[Point] = []

scala> hs.add(Point(2))
res13: Boolean = true

scala> hs.add(Point(3))
res14: Boolean = true

scala> val javaRDD = new JavaPairRDD(sc.parallelize(Seq((Polygon("a"), hs))))
javaRDD: org.apache.spark.api.java.JavaPairRDD[Polygon,java.util.HashSet[Point]] = org.apache.spark.api.java.JavaPairRDD@14fc37a
使用Scala RDD 通过使用
.RDD
,可以从Java RDD检索底层Scala RDD:

scala> javaRDD.rdd.map(outCountPerCell).foreach(println)
(Polygon(a),5)
更好的方法是将
mapValues
与Scala RDD结合使用 由于只有元组的第二部分在更改,因此可以使用
.mapValues
干净地解决此问题:

scala> javaRDD.rdd.mapValues(_.asScala.map(_.ordinate).sum).foreach(println)
(Polygon(a),5)

谢谢你。我通过删除tuple2尝试了上述方法。我能够保存这个函数。当试图调用函数时,它抛出以下错误
scala>joinResult.map(outCountPerCell()).foreach(println):82:错误:扩展函数((x$1)=>outCountPerCell(x$1))缺少参数类型joinResult.map(outCountPerCell()).foreach(println)
我的输入对RDD有一个java.util.HashSet,而不是scala的HashSet。你知道这会导致这个问题吗
scala>val joinResult=JoinQuery.SpatialJoinQuery(myPointsRDD,myPolygonRDD,true,true)joinResult:org.apache.spark.api.java.javaPairdd[com.livitSolutions.jts.geom.Polygon,java.util.HashSet[com.livitSolutions.jts.geom.Point]]=org.apache.spark.api.java。JavaPairRDD@3dc4e185
@IWonderHow它与
java.util.HashSet
一起工作。
joinResult
的类型是什么?尝试
println(joinResult.getClass)
它是一个javaPairRDD。scala>println(joinResult.getClass)类org.apache.spark.api.java.javapairdd谢谢evan,它成功了!!非常感谢你抽出时间来帮忙。我必须使用
导入scala.collection.JavaConverters.\u
才能使用.asscala谢谢evan058。我通过删除tuple2尝试了上述方法。我能够保存这个函数。当试图调用函数时,它抛出以下错误
scala>joinResult.map(outCountPerCell()).foreach(println):82:错误:扩展函数((x$1)=>outCountPerCell(x$1))缺少参数类型joinResult.map(outCountPerCell()).foreach(println)
我的输入对RDD有一个java.util.HashSet,而不是scala的HashSet。你知道这会导致这个问题吗
scala>val joinResult=JoinQuery.SpatialJoinQuery(myPointsRDD,myPolygonRDD,true,true)joinResult:org.apache.spark.api.java.javaPairdd[com.livitSolutions.jts.geom.Polygon,java.util.HashSet[com.livitSolutions.jts.geom.Point]]=org.apache.spark.api.java。JavaPairRDD@3dc4e185
@IWonderHow它与
java.util.HashSet
一起工作。
joinResult
的类型是什么?尝试
println(joinResult.getClass)
它是一个javaPairRDD。scala>println(joinResult.getClass)类org.apache.spark.api.java.javapairdd谢谢evan,它成功了!!非常感谢你抽出时间来帮忙。为了使用.asScala,我必须使用
导入scala.collection.JavaConverters.\u