我有两个scala.collection.Iterable
我希望转换为java.util.List
或更高效的Java 8馆藏。有效的方法是什么?我是Scala的新手,我找到了JavaConversions,但我正在努力了解这样做的有效方法,因为我要在Apache Spark中处理超过5亿件物品。
上下文
我的Java API采用List(或者我可以将API更改为您建议的任何内容)并迭代所有项目(顺序无关紧要)以创建单个结果。
答案 0 :(得分:1)
如果你在java中只迭代一次,java的Iterable
应该在这里做得很好。
它应该相当快,因为转换的实现看起来像这样(非常简单的包装器):
trait IterableWrapperTrait[A] extends ju.AbstractCollection[A] {
val underlying: Iterable[A]
def size = underlying.size
override def iterator = IteratorWrapper(underlying.iterator)
override def isEmpty = underlying.isEmpty
}
case class IteratorWrapper[A](underlying: Iterator[A]) extends ju.Iterator[A] with ju.Enumeration[A] {
def hasNext = underlying.hasNext
def next() = underlying.next()
def hasMoreElements = underlying.hasNext
def nextElement() = underlying.next()
def remove() = throw new UnsupportedOperationException
}
要使用它,您需要导入
import scala.collection.JavaConverters._
并在您的scala asJava
上调用Iterable
方法。或者你可以拿一个迭代器并为它做同样的事情,无所谓。
关于JavaConverters
vs JavaConversions
的小记。第一个要求您在集合中明确调用asScala
和asJava
,这被认为更具可读性,而后者则使用隐式转换,对于必须阅读它的人来说可能会变得神秘。
修改强>
我不确定我是否理解正确,但我认为你可能想先合并两个iterables然后将它们传递给java?
如果是这样,你可以使用迭代器:
val c1: Iterable[Int] = ???
val c2: Iterable[Int] = ???
val merged: Iterator[Int] = Iterator(c1.iterator, c2.iterator).flatten
val javaVersion: java.util.Iterator[Int] = merged.asJava