Учитывая Iterator<Element>
, как мы можем преобразовать этот Iterator
в ArrayList<Element>
(или List<Element>
) в лучший и быстрый способ, так что мы можем использовать операции ArrayList
на нем, например, get(index)
, add(element)
и т.д.
Преобразовать Iterator в ArrayList
Ответ 1
Лучше использовать библиотеку, например Guava:
import com.google.common.collect.Lists;
Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
Другой пример Guava:
ImmutableList.copyOf(myIterator);
или Коллекции сообщества Apache:
import org.apache.commons.collections.IteratorUtils;
Iterator<Element> myIterator = ...//some iterator
List<Element> myList = IteratorUtils.toList(myIterator);
Ответ 2
В Java 8 вы можете использовать новый метод forEachRemaining
, добавленный в интерфейс Iterator
:
List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
Ответ 3
Вы можете скопировать итератор в новый список следующим образом:
Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
copy.add(iter.next());
Предположим, что список содержит строки. На самом деле не существует более быстрого способа воссоздать список из итератора, вы застреваете его вручную и копируете каждый элемент в новый список соответствующего типа.
EDIT:
Вот общий метод для копирования итератора в новый список безопасным способом:
public static <T> List<T> copyIterator(Iterator<T> iter) {
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
Используйте его следующим образом:
List<String> list = Arrays.asList("1", "2", "3");
Iterator<String> iter = list.iterator();
List<String> copy = copyIterator(iter);
System.out.println(copy);
> [1, 2, 3]
Ответ 4
Вы также можете использовать IteratorUtils
из Apache commons-collections, хотя он не поддерживает дженерики:
List list = IteratorUtils.toList(iterator);
Ответ 5
С помощью java 8 вы можете использовать это решение:
Iterable<Element> iterator = createIterator();
List<Element> array = StreamSupport
.stream(iterator.spliterator(), false)
.collect(Collectors.toList());
Как я знаю, Collectors.toList()
создает экземпляр ArrayList
.
На самом деле, на мой взгляд, он также хорошо выглядит в одной строке.
Например, если вам нужно вернуть List<Element>
из некоторого метода:
return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Ответ 6
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
Ответ 7
Довольно сжатое решение с простой Java 8, используя java.util.stream
:
public static <T> ArrayList<T> toArrayList(final Iterator<T> iterator) {
return StreamSupport
.stream(
Spliterators
.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
.collect(
Collectors.toCollection(ArrayList::new)
);
}
Ответ 8
Java 8 forEachRemaining метод в Iterator можно использовать здесь:
List<Element> elementList = new ArrayList<>(); iterator.forEachRemaining(elementList::add);
Ответ 9
используйте google guava!
Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);
++
Ответ 10
Попробуйте StickyList
из Cactoos:
List<String> list = new StickyList<>(iterator);
Отказ от ответственности: я один из разработчиков.
Ответ 11
Я просто хочу указать на кажущееся очевидное решение, что НЕ будет работать:
List list = Stream.generate(iterator::next) .collect(Collectors.toList());
Это потому, что Stream#generate(Supplier<T>)
может создавать только бесконечные потоки, он не ожидает, что его аргумент будет бросать NoSuchElementException
(что в конце концов будет Iterator#next()
).
Вместо этого следует использовать ответ xehpuk, если вам нужен вариант Iterator → Stream → List.
Ответ 12
Здесь в этом случае, если вам нужен самый быстрый способ, лучше for loop
.
Итератор по размеру выборки 10,000 runs
принимает 40 ms
, где для цикла принимает значение 2 ms
ArrayList<String> alist = new ArrayList<String>();
long start, end;
for (int i = 0; i < 1000000; i++) {
alist.add(String.valueOf(i));
}
ListIterator<String> it = alist.listIterator();
start = System.currentTimeMillis();
while (it.hasNext()) {
String s = it.next();
}
end = System.currentTimeMillis();
System.out.println("Iterator start: " + start + ", end: " + end + ", delta: "
+ (end - start));
start = System.currentTimeMillis();
int ixx = 0;
for (int i = 0; i < 100000; i++) {
String s = alist.get(i);
}
System.out.println(ixx);
end = System.currentTimeMillis();
System.out.println("for loop start: " + start + ", end: " + end + ", delta: "
+ (end - start));
Предположим, что список содержит строки.