Создайте неизменный список из java.lang.Iterator
Я использую библиотеку ( JXPath) для запроса графа бинов, чтобы извлечь соответствующие элементы. Тем не менее, JXPath возвращает группы соответствующих элементов в качестве экземпляра java.lang.Iterator, и я бы предпочел преобразовать его в неизменный список scala. Есть ли более простой способ сделать, чем перебирать итератор и создавать новый неизменный список на каждом шаге итерации?
2 ответа
Вы можете переосмыслить необходимость List
, хотя это кажется очень знакомым при переходе с Java, и List является реализацией неизменяемого по умолчанию Seq
часто это не лучший выбор коллекции.
Операции, для которых этот список является оптимальным, - это те, которые уже доступны через итератор (в основном, с использованием последовательных элементов заголовка и предшествующих элементов). Если итератор уже не дает вам то, что вам нужно, то я могу в значительной степени гарантировать, что List не будет вашим лучшим выбором - вектор будет более подходящим.
Разобравшись с этим... Рекомендованный метод для преобразования между коллекциями Java и Scala (начиная с Scala 2.8.1) - через scala.collection.JavaConverters
, Это дает вам больше контроля, чем JavaConversions
и избегает некоторых возможных неявных конфликтов.
У вас не будет прямого неявного преобразования таким образом. Вместо этого вы получаете asScala
а также asJava
методы, встроенные в коллекции, позволяющие явно выполнять преобразования.
Чтобы преобразовать итератор Java в итератор Scala:
javaIterator.asScala
Чтобы преобразовать итератор Java в список Scala (с помощью итератора scala):
javaIterator.asScala.toList
Вы также можете рассмотреть возможность преобразования toSeq
вместо toList
, В случае итераторов это вернет Stream
- позволяя сохранить ленивое поведение итераторов в более богатых Seq
интерфейс.
РЕДАКТИРОВАТЬ: Там нет toVector
метод, но (как указал Даниэль) есть toIndexedSeq
метод, который будет возвращать Vector
по умолчанию IndexedSeq
подкласс (так же, как List
по умолчанию Seq
).
javaIterator.asScala.toIndexedSeq
РЕДАКТИРОВАТЬ: Вам, вероятно, следует взглянуть на ответ Кевина Райта, который предоставляет лучшее решение, доступное начиная с Scala 2.8.1, с менее скрытой магией.
Вы можете импортировать неявные преобразования из scala.collection.JavaConversions
а затем без проблем создайте новую коллекцию Scala, например, так:
import collection.JavaConversions._
println(List() ++ javaIterator)
Ваш итератор Java преобразуется в итератор Scala JavaConversions.asScalaIterator
, Итератор Scala с элементами типа A
инвентарь TraversableOnce[A]
, который является типом аргумента, необходимого для объединения коллекций с ++
,
Если вам нужен другой тип коллекции, просто измените List()
на все, что вам нужно (например, IndexedSeq()
или же collection.mutable.Seq()
, так далее.).