25

我正在使用库 ( JXPath ) 来查询 bean 图以提取匹配元素。但是,JXPath 将匹配元素组作为 java.lang.Iterator 的实例返回,我宁愿将其转换为不可变的 scala 列表。有没有比迭代迭代器并在每个迭代步骤创建一个新的不可变列表更简单的方法?

4

2 回答 2

35

您可能想重新考虑对 a 的需求List,虽然它在来自 Java 时感觉非常熟悉,并且 List 是 immutable 的默认实现Seq,但它通常不是集合的最佳选择。

list 最适合的操作是那些已经通过迭代器可用的操作(基本上采用连续的头元素和前置元素)。如果迭代器还没有给你你需要的东西,那么我几乎可以保证 List 不会是你的最佳选择——向量会更合适。


解决了这个问题...在 Java 和 Scala 集合之间进行转换的推荐技术(自 Scala 2.8.1 起)是 via scala.collection.JavaConverters。这为您提供了更多的控制权,JavaConversions并避免了一些可能的隐含冲突。

这种方式不会有直接的隐式转换。取而代之的是,您将获取asScalaasJava方法添加到集合中,从而允许您显式地执行转换。

要将 Java 迭代器转换为 Scala 迭代器:

javaIterator.asScala

将 Java 迭代器转换为 Scala 列表(通过 scala 迭代器):

javaIterator.asScala.toList

您可能还需要考虑转换toSeq而不是toList. 对于迭代器,这将返回一个- 允许您在更丰富的接口Stream中保留迭代器的惰性行为。Seq

编辑: 没有toVector方法,但是(正如丹尼尔指出的那样)有一个toIndexedSeq方法将返回 aVector作为默认IndexedSeq子类(就像Listdefault一样Seq)。

javaIterator.asScala.toIndexedSeq
于 2011-05-16T09:22:28.610 回答
8

编辑:您可能应该看看Kevin Wright 的回答,它提供了自 Scala 2.8.1 以来更好的解决方案,并且隐含的魔法更少。


您可以从中导入隐式转换scala.collection.JavaConversions,然后无缝地创建一个新的 Scala 集合,例如:

import collection.JavaConversions._
println(List() ++ javaIterator)

您的 Java 迭代器通过JavaConversions.asScalaIterator. 具有类型元素的 Scala 迭代器A实现TraversableOnce[A],这是连接集合所需的参数类型++

如果您需要其他集合类型,只需更改List()为您需要的任何内容(例如,IndexedSeq()collection.mutable.Seq()等)。

于 2011-05-16T08:43:24.767 回答