I'm using a library (JXPath) to query a graph of beans in order to extract matching elements. However, JXPath returns groups of matching elements as an instance of java.lang.Iterator and I'd rather like to convert it into an immutable scala list. Is there any simpler way of doing than iterating over the iterator and creating a new immutable list at each iteration step ?
You might want to rethink the need for a List
, although it feels very familiar when coming from Java, and List is the default implementation of an immutable Seq
, it often isn't the best choice of collection.
The operations that list is optimal for are those already available via an iterator (basically taking consecutive head elements and prepending elements). If an iterator doesn't already give you what you need, then I can pretty much guarantee that a List won't be your best choice - a vector would be more appropriate.
Having got that out the way... The recommended technique to convert between Java and Scala collections (since Scala 2.8.1) is via scala.collection.JavaConverters
. This gives you more control than JavaConversions
and avoids some possible implicit conflicts.
You won't have a direct implicit conversion this way. Instead, you get asScala
and asJava
methods pimped onto collections, allowing you to perform the conversions explicitly.
To convert a Java iterator to a Scala iterator:
javaIterator.asScala
To convert a Java iterator to a Scala List (via the scala iterator):
javaIterator.asScala.toList
You may also want to consider converting toSeq
instead of toList
. In the case of iterators, this'll return a Stream
- allowing you to retain the lazy behaviour of iterators within the richer Seq
interface.
EDIT:
There's no toVector
method, but (as Daniel pointed out) there's a toIndexedSeq
method that will return a Vector
as the default IndexedSeq
subclass (just as List
is the default Seq
).
javaIterator.asScala.toIndexedSeq