Создайте неизменный список из 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(), так далее.).

Другие вопросы по тегам