java итератор <?> - Преобразовать Iterator в ArrayList




6 Answers

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

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);       
перебор iterators

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




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

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]



Обратите внимание, что существует разница между 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());



List result = new ArrayList();
while (i.hasNext()){
    result.add(i.next());
}



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

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

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




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

List list = Stream.generate(iterator::next)
    .collect(Collectors.toList());

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

share следует использовать share если вы выбираете путь Iterator → Stream → List.




Related