scala - Crea una lista inmutable desde un java.lang.Iterator
scala-collections scala-java-interop (2)
EDITAR: Probablemente debería ver la respuesta de Kevin Wright , que proporciona una mejor solución disponible desde Scala 2.8.1, con menos magia implícita.
Puede importar las conversiones implícitas de scala.collection.JavaConversions
y luego crear una nueva colección de Scala a la perfección, por ejemplo, de esta forma:
import collection.JavaConversions._
println(List() ++ javaIterator)
Su iterador de Java se convierte en un iterador de Scala mediante JavaConversions.asScalaIterator
. Un iterador Scala con elementos de tipo A
implementa TraversableOnce[A]
, que es el tipo de argumento necesario para concatenar colecciones con ++
.
Si necesita otro tipo de colección, simplemente cambie List()
a lo que necesite (por ejemplo, IndexedSeq()
o collection.mutable.Seq()
, etc.).
Estoy usando una biblioteca ( JXPath ) para consultar un gráfico de beans para extraer elementos coincidentes. Sin embargo, JXPath devuelve grupos de elementos coincidentes como una instancia de java.lang.Iterator y me gustaría convertirlo en una lista de Scala inmutable. ¿Hay alguna forma más sencilla de hacerlo que iterar sobre el iterador y crear una nueva lista inmutable en cada paso de la iteración?
Es posible que desee reconsiderar la necesidad de una List
, aunque se siente muy familiar cuando se trata de Java, y la Lista es la implementación predeterminada de una Seq
inmutable, a menudo no es la mejor opción de colección.
Las operaciones en las que la lista es óptima son aquellas que ya están disponibles a través de un iterador (básicamente, toman elementos de cabecera consecutivos y elementos en preparación). Si un iterador no te da lo que necesitas, entonces puedo garantizarte que una lista no será tu mejor opción: un vector sería más apropiado.
Habiendo logrado eso ... La técnica recomendada para convertir colecciones de Java y Scala (desde Scala 2.8.1) es a través de scala.collection.JavaConverters
. Esto le da más control que JavaConversions
y evita algunos posibles conflictos implícitos.
No tendrás una conversión implícita directa de esta manera. En su lugar, asJava
métodos asScala
y asJava
en las colecciones, lo que te permite realizar las conversiones explícitamente.
Para convertir un iterador de Java en un iterador de Scala:
javaIterator.asScala
Para convertir un iterador de Java en una lista de Scala (a través del iterador de scala):
javaIterator.asScala.toList
También es posible que desee considerar la conversión de toSeq
lugar de toList
. En el caso de los iteradores, esto devolverá un Stream
, permitiéndole retener el comportamiento perezoso de los iteradores dentro de la interfaz Seq
más rica.
EDIT: No hay toVector
método toVector
, pero (como Daniel señaló) hay un método toIndexedSeq
que devolverá un Vector
como la subclase IndexedSeq
predeterminada (al igual que List
es la Seq
predeterminada).
javaIterator.asScala.toIndexedSeq