web-dev-qa-db-fra.com

Convertir l'itérateur en ArrayList

Étant donné Iterator<Element>, comment pouvons-nous convertir cette Iterator en ArrayList<Element> (ou List<Element>) de la manière meilleure et rapide possible, afin que nous puissions utiliser les opérations de ArrayList telles que get(index), add(element), etc.

205
Maksim

Mieux vaut utiliser une bibliothèque comme Guava :

import com.google.common.collect.Lists;

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

Un autre exemple de goyave:

ImmutableList.copyOf(myIterator);

ou Collections Apache Commons :

import org.Apache.commons.collections.IteratorUtils;

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

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

En Java 8, vous pouvez utiliser la nouvelle méthode forEachRemaining qui a été ajoutée à l'interface Iterator:

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

Vous pouvez copier un itérateur dans une nouvelle liste comme celle-ci:

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

Cela suppose que la liste contient des chaînes. Il n'y a pas vraiment de moyen plus rapide de recréer une liste à partir d'un itérateur, vous êtes obligé de la parcourir manuellement et de copier chaque élément dans une nouvelle liste du type approprié.

MODIFIER :

Voici une méthode générique pour copier un itérateur dans une nouvelle liste de manière sécurisée:

public static <T> List<T> copyIterator(Iterator<T> iter) {
    List<T> copy = new ArrayList<T>();
    while (iter.hasNext())
        copy.add(iter.next());
    return copy;
}

Utilisez-le comme ceci:

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

Vous pouvez également utiliser IteratorUtils from Apache commons-collections , bien qu'il ne prenne pas en charge les génériques:

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

Notez qu'il existe une différence entre Iterable et Iterator .

Si vous avez Iterable, avec Java 8, vous pouvez utiliser cette solution:

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

Comme je le sais, Collectors.toList() crée une instance ArrayList.

En fait, à mon avis, cela semble également bon dans une ligne.
Par exemple, si vous devez renvoyer List<Element> depuis une méthode:

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

Solution assez concise avec Java 8 simple utilisant 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

La méthode Java 8 forEachRemaining dans Iterator peut être utilisée ici:

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

Essayez StickyList from Cactoos :

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

Disclaimer: Je suis l'un des développeurs.

1
yegor256

utilisez google goyave !

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

++

0
fedevo

Je veux simplement signaler une solution apparemment évidente qui ne fonctionnera PAS:

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

C'est parce que Stream#generate(Supplier<T>) ne peut créer que des flux infinis, il ne s'attend pas à ce que son argument jette NoSuchElementException (c'est ce que Iterator#next() fera à la fin).

La réponse du xehpuk devrait être utilisée à la place si la méthode Itérateur → Flux → Liste est votre choix.

0
Sasha