Вопрос по list, iterator, arraylist, java – Конвертировать Iterator в ArrayList

206

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

Ваш Ответ

12   ответов
4

List<Element> elementList = new ArrayList<>(); 
iterator.forEachRemaining(elementList::add);
Это именно то, что Стюарт Марксanswer говорит, что делать было опубликовано за 2 с половиной года до этого ответа.
327

гуайява:

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);       
@CorayThan меньше кода + проверенные методы. Хотя я согласен с вами, я бы не стал добавлять дополнительную зависимость только для использования этого метода. Но опять же, большинство моих (больших) проектов используют либо Guava, либо Apache Commons ...
Согласна с Рено и Стефаном. Кроме того, если вы используете инструмент сборки, включить эти библиотеки проще всего в мире ... ТАКЖЕ ... если вы действительно не хотите включать их, вы можете перейти к исходному коду Apache / Guava. закодируйте и скопируйте то, что они там сделали: НАМНОГО лучше, чем тратить свое время на то, чтобы заново изобрести сотни прекрасно спроектированных и проверенных колес, которые уже существуют.
@CorayThan Разделяй и властвуй, мой друг. Зачем писать метод, который уже предоставлен библиотекой и протестирован? Мы используем много Apache Commons и Guava, они просто потрясающие и помогают вам сэкономить время и деньги.
Я не понимаю. Каким образом ArrayList возвращается, скажем, Guava лучше, чем обычный ArrayList? Они делают это более эффективным способом? Даже если он более эффективен, стоит ли добавлять дополнительную зависимость (и более сложную) в ваш проект?
199

forEachRemaining метод, который был добавлен кIterator интерфейс:

List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
что значит::? какое имя у него есть? кажется прямой ссылкой на list.add (); и кажется также некоторая новая вещь java8; и спасибо! :)
@javadba Первоначальный вопрос был о том, как преобразовать имеющийся у вас итератор в новый ArrayList. В этом примере предполагается, что уже имеющийся у вас итераторiterator.
Это должен быть принятый ответ, так как он самый короткий и не зависит от сторонних библиотек.
гдеiterator приходящий из? это неразрешенный символ
@ AquariusPower The:: синтаксис является новым в Java 8, и он ссылается на «ссылку на метод», quot; которая является сокращенной формой лямбды. Смотрите здесь для получения дополнительной информации:docs.oracle.com/javase/tutorial/java/javaOO/…
-2

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));  

Это предполагает, что список содержит строки.

Это твой звонок. Я бы еще не удалил его, он может быть информативным. Я удаляю свои ответы только тогда, когда люди начинают их понижать :)
Конечно, используяfor доступ к элементам списка с помощьюget(i) быстрее, чем использование итератора ... но это не то, о чем спрашивал ОП, он специально упомянул, чтоiterator дается в качестве ввода.
@ Оскар, прости. Должен ли я удалить свой ответ?
Да, итератор был задан как ввод, @ & # xD3; scarL & # xF3; pez был прав. Maksim
@ Оскар спасибо. Тогда я буду ждать первого голосования вниз :)
1

ПытатьсяStickyList отCactoos:

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

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

@ xehpuk сделано, теперь все в порядке :)
Это не отвечает на вопрос.Iterable != Iterator
Отлично, теперь вам, вероятно, нужно сгенерировать JavaDoc для новой версии и обновить ссылку. :)
@xehpuk я обновил ответ
5
List result = new ArrayList();
while (i.hasNext()){
    result.add(i.next());
}
Код в порядке. В его случае я являюсь итератором & lt; Element & gt; Maksim
что с этим кодом? он даже не компилируется
@LuggiMendoza: Переполнение стека не предназначено для того, чтобы вы могли просто вырезать, вставлять и решать свою проблему. Это должно быть информативно. Это совершенно информативный ответ, и любой разумный человек должен иметь возможность собрать его, чтобы я был итератором. Судя по звукам, вы почти не прикладываете усилий, пытаясь понять, что происходит.
это должно быть в коде, как это сделал @OscarLopez
6

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)
    );
}
@Sergio Это не короткое, но единственное выражение, которое имеет огромное значение.
@ Sergio Вот почему я написал "довольно". Однако ему не нужны локальные переменные и только одна точка с запятой. Вы можете сократить его с помощью статического импорта.
Я бы сказалiterator.forEachRemaining( list::add )также новый в Java 8, намного более кратким. Перемещение списка переменных вCollector не улучшает читаемость в этом случае, так как он должен поддерживатьсяStream иSpliterator.
Я бы не назвал это решение "кратким".
Есть ли более компактный способ написать это с помощью потокового API? Кажется, не проще, чем обычный цикл while.
15

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());
согласен с приведенным выше комментарием. очень запутанно, что вы назвали свойIterable iterator, Они естьcompletely разные.
Вопрос об итераторе & lt; Element & gt; в качестве отправной точки, а не Iterable & lt; Element & gt ;.
В Java 8 вы можете легко конвертироватьIterator вернуться кsingle use Iterable используя() -> iterator, Это может быть полезно в подобных ситуациях, но позвольте мне еще раз подчеркнуть важную вещь: вы можете использовать этот метод, только еслиsingle use Iterable приемлемо призваниеiterable.iterator() более одного раза даст неожиданные результаты. Приведенный выше ответ становитсяIterator<Element> iterator = createIterator(); List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
61

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]
0

will NOT Работа:

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

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

Ответ xehpuk'а следует использовать вместо этого, если ваш выбор - Итератор & Stream & # x2192; Список.

0

гуайява !

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

++

Итератор (не итерируемый) для ArrayList
20

IteratorUtils от ApacheВикисклад коллекцияхотя он не поддерживает генерики:

List list = IteratorUtils.toList(iterator);
Он также имеет 2 метода toArray и 1 принимает тип:commons.apache.org/proper/commons-collections/javadocs/…, java.lang.Class)

Похожие вопросы