Преобразовать Iterator в ArrayList

Учитывая Iterator<Element>, как мы можем преобразовать этот Iterator в ArrayList<Element> (или List<Element>) в лучший и быстрый способ, так что мы можем использовать операции ArrayList на нем, например, get(index), add(element) и т.д.

Ответ 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));  

Предположим, что список содержит строки.