Подтвердить что ты не робот

Создайте неизменный список из java.lang.Iterator

Я использую библиотеку (JXPath) для запроса графика beans для извлечения соответствующих элементов. Однако JXPath возвращает группы совпадающих элементов как экземпляр java.lang.Iterator, и я бы предпочел преобразовать его в неизменяемый список scala. Есть ли более простой способ сделать, чем итерация по итератору и создание нового неизменяемого списка на каждом этапе итерации?

4b9b3361

Ответ 1

Возможно, вам захочется переосмыслить потребность в List, хотя она очень хорошо знакома при использовании Java, а List - это реализация неизменяемого Seq по умолчанию, это часто не лучший выбор для коллекции.

Операциями, список которых является оптимальным, являются те, которые уже доступны через итератор (в основном, с последующими элементами заголовка и добавочными элементами). Если итератор уже не дает вам то, что вам нужно, я могу в значительной степени гарантировать, что список не будет вашим лучшим выбором - вектор будет более уместным.


Получив это из-за... Рекомендуемый метод преобразования между сборками 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.

EDIT: Нет метода toVector, но (как указал Даниил) существует метод toIndexedSeq, который вернет Vector в качестве стандартного подкласса IndexedSeq (так же, как List является значением по умолчанию Seq).

javaIterator.asScala.toIndexedSeq

Ответ 2

РЕДАКТИРОВАТЬ: Вероятно, вы должны посмотреть на ответ Кевина Райт, который обеспечивает лучшее решение, доступное с 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() и т.д.).