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