scala scala-collections scala-java-interop jxpath

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