it-roy-ru.com

Конвертировать Iterator в ArrayList

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

205
Maksim

Лучше использовать библиотеку, как Гуава :

import com.google.common.collect.Lists;

Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);

Еще один пример гуавы:

ImmutableList.copyOf(myIterator);

или Коллекции Apache Commons :

import org.Apache.commons.collections.IteratorUtils;

Iterator<Element> myIterator = ...//some iterator

List<Element> myList = IteratorUtils.toList(myIterator);       
327
Renaud

В Java 8 вы можете использовать новый метод forEachRemaining, который был добавлен в интерфейс Iterator:

List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
197
Stuart Marks

Вы можете скопировать итератор в новый список, например так:

Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
    copy.add(iter.next());

Это при условии, что список содержит строки. На самом деле не существует более быстрого способа воссоздания списка из итератора, вы застряли на том, чтобы обходить его вручную и копировать каждый элемент в новый список соответствующего типа.

Правка :

Вот общий метод для копирования итератора в новый список безопасным для типов способом:

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]
61
Óscar López

Вы также можете использовать IteratorUtils из Apache commons-collection , хотя он не поддерживает обобщения:

List list = IteratorUtils.toList(iterator);
20
yegor256

Обратите внимание, что есть разница между Iterable и Iterator .

Если у вас есть Iterable, то с Java 8 вы можете использовать это решение:

Iterable<Element> iterable = createIterable();
List<Element> array = StreamSupport
    .stream(iterable.spliterator(), false)
    .collect(Collectors.toList());

Как я знаю Collectors.toList() создает ArrayList экземпляр.

На самом деле, на мой взгляд, это также хорошо выглядит в одной строке.
Например, если вам нужно вернуть List<Element> из какого-либо метода:

return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
15
Dub Nazar

Довольно краткое решение с простой 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)
    );
}
6
xehpuk
List result = new ArrayList();
while (i.hasNext()){
    result.add(i.next());
}
5
Akvel

Метод Java 8 forEachRemaining в Iterator можно использовать здесь:

List<Element> elementList = new ArrayList<>(); 
iterator.forEachRemaining(elementList::add);
4
crazy_coder

Попробуйте StickyList от Cactoos :

List<String> list = new StickyList<>(iterator);

Отказ от ответственности: я один из разработчиков.

1
yegor256

используйте Google Гуава !

Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);

++

0
fedevo

Я просто хочу указать на кажущееся очевидным решение, что НЕ будет работать:

Список list = Stream.generate (iterator :: next) 
 .collect (Collectors.toList ());

Это потому, что Stream#generate(Supplier<T>) может создавать только бесконечные потоки, он не ожидает, что его аргумент сгенерирует NoSuchElementException (это то, что Iterator#next() сделает в конце).

Вместо этого следует использовать ответ xehpuk , если вы выбрали путь Iterator → Stream → List.

0
Sasha