将两个scala.collection.Iterable转换为Java List或Iterator

时间:2016-01-12 20:25:35

标签: java scala apache-spark

我有两个scala.collection.Iterable我希望转换为java.util.List或更高效的Java 8馆藏。有效的方法是什么?我是Scala的新手,我找到了JavaConversions,但我正在努力了解这样做的有效方法,因为我要在Apache Spark中处理超过5亿件物品。

上下文

我的Java API采用List(或者我可以将API更改为您建议的任何内容)并迭代所有项目(顺序无关紧要)以创建单个结果。

1 个答案:

答案 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的小记。第一个要求您在集合中明确调用asScalaasJava,这被认为更具可读性,而后者则使用隐式转换,对于必须阅读它的人来说可能会变得神秘。

修改

我不确定我是否理解正确,但我认为你可能想先合并两个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