Rom*_*voy 22 scala jxpath scala-java-interop scala-collections
我正在使用库(JXPath)来查询bean的图形以便提取匹配的元素.但是,JXPath返回匹配元素组作为java.lang.Iterator的实例,我更愿意将其转换为不可变的scala列表.有没有比在迭代器上迭代并在每个迭代步骤创建一个新的不可变列表更简单的方法?
Kev*_*ght 34
你可能想重新考虑a的需要List,虽然从Java来的时候感觉非常熟悉,而List是不可变的默认实现Seq,但它往往不是收集的最佳选择.
列表最佳的操作是通过迭代器已经可用的操作(基本上采用连续的头元素和前置元素).如果迭代器还没有给你你需要的东西,那么我几乎可以保证List不是你的最佳选择 - 矢量会更合适.
已经解决了这个问题...在Java和Scala集合之间进行转换的推荐技术(自Scala 2.8.1起)是通过的scala.collection.JavaConverters.这使您可以更多地控制JavaConversions并避免一些可能的隐式冲突.
您不会以这种方式进行直接隐式转换.相反,您可以将方法asScala和asJavapimped一起放到集合上,从而允许您明确地执行转换.
要将Java迭代器转换为Scala迭代器:
javaIterator.asScala
Run Code Online (Sandbox Code Playgroud)
要将Java迭代器转换为Scala列表(通过scala迭代器):
javaIterator.asScala.toList
Run Code Online (Sandbox Code Playgroud)
您可能还想考虑转换toSeq而不是toList.在迭代器的情况下,这将返回Stream- 允许您在更丰富的Seq接口中保留迭代器的惰性行为.
编辑:
没有toVector方法,但(正如丹尼尔指出的那样)有一个toIndexedSeq方法将返回一个Vector默认IndexedSeq子类(就像List默认的那样Seq).
javaIterator.asScala.toIndexedSeq
Run Code Online (Sandbox Code Playgroud)
编辑:你应该看看Kevin Wright的答案,它提供了一个更好的解决方案,自Scala 2.8.1以来,具有更少的隐含魔法.
您可以从中导入隐式转换scala.collection.JavaConversions,然后无缝地创建新的Scala集合,例如:
import collection.JavaConversions._
println(List() ++ javaIterator)
Run Code Online (Sandbox Code Playgroud)
您的Java迭代器将转换为Scala迭代器JavaConversions.asScalaIterator.具有类型Aimplements 元素的Scala迭代器TraversableOnce[A],它是连接集合所需的参数类型++.
如果您需要其他集合类型,只需更改List()为您需要的任何类型(例如,IndexedSeq()或collection.mutable.Seq()等).