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