如何将嵌套的scala集合转换为嵌套的Java集合

我在Scala和Java之间有编译问题。

我的Java代码需要一个

java.util.Map<Double, java.lang.Iterable> 

我的scala代码有一个

 Map[Double, Vector[Foo]] 

我收到编译错误:

 error: type mismatch; found : scala.collection.immutable.Map[scala.Double,Vector[Foo] required: java.util.Map[java.lang.Double,java.lang.Iterable[Foo]] 

似乎scala.collection.JavaConversions不适用于嵌套集合,即使Vector可以被隐式转换为Iterable。 没有迭代scala集合并手动进行转换,我可以做些什么来使类型工作?

scala.collection.JavaConversions应该被弃用恕我直言。 最好通过使用scala.collection.JavaConverters来明确转换发生的位置和时间。 在你的情况下:

 import scala.collection.JavaConverters._ type Foo = Int // Just to make it compile val scalaMap = Map(1.0 -> Vector(1, 2)) // As an example val javaMap = scalaMap.map { case (d, v) => d -> v.toIterable.asJava }.asJava 

我写了这个通用function,它可以很好地满足我的需求。

 def toJava(x: Any): Any = { import scala.collection.JavaConverters._ x match { case y: scala.collection.MapLike[_, _, _] => y.map { case (d, v) => toJava(d) -> toJava(v) } asJava case y: scala.collection.SetLike[_,_] => y map { item: Any => toJava(item) } asJava case y: Iterable[_] => y.map { item: Any => toJava(item) } asJava case y: Iterator[_] => toJava(y.toIterable) case _ => x } } 

这更适合我的需求:

  def toJava(m: Any): Any = { import java.util import scala.collection.JavaConverters._ m match { case sm: Map[_, _] => sm.map(kv => (kv._1, toJava(kv._2))).asJava case sl: Iterable[_] => new util.ArrayList(sl.map( toJava ).asJava.asInstanceOf[util.Collection[_]]) case _ => m } } 

如果有人在火花scala中寻找解决方案,请试试这个

import org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema

这里,y是嵌套的WrapperArray

 y match { case x : WrappedArray[x] => (x.map(f => f match {case z: GenericRowWithSchema => z.mkString(",").toString() case z:Any => z })).asJavaCollection case _ => row.get(i).asInstanceOf[Object] } 

上面的代码,做了两件事,1)如果包装器Array有原始数据类型,条件case_通过2)如果包装器Array有复杂数据类型(比如struts),则执行GenericRowWithSchema。