Réponses:
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);
Dans Java 8, vous pouvez utiliser la nouvelle forEachRemaining
méthode qui a été ajoutée à l' Iterator
interface:
List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
::
? quel nom a-t-il? semble une référence directe à list.add (); et semble aussi quelque chose de nouveau java8; et merci! :)
::
syntaxe est nouvelle dans Java 8 et fait référence à une "référence de méthode", qui est une forme abrégée d'un lambda. Voir ici pour plus d'informations: docs.oracle.com/javase/tutorial/java/javaOO/…
iterator
vient-il? c'est un symbole non résolu
iterator
.
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 vraiment pas de moyen plus rapide de recréer une liste à partir d'un itérateur, vous êtes obligé de le parcourir à la main et de copier chaque élément dans une nouvelle liste du type approprié.
ÉDITER :
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]
Notez qu'il y a une différence entre Iterable
et Iterator
.
Si vous en avez un Iterable
, alors 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 sais, Collectors.toList()
crée une ArrayList
instance.
En fait, à mon avis, cela semble également bien sur une seule ligne.
Par exemple, si vous devez revenir List<Element>
d'une méthode:
return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Iterable
iterator
. Ils sont complètement différents.
Iterator
dos en une seule utilisation Iterable
en utilisant () -> iterator
. Cela peut être utile dans des situations comme celle-ci, mais permettez-moi de souligner à nouveau la chose importante: vous ne pouvez utiliser cette méthode que si une seule utilisation Iterable
est acceptable. Appeler iterable.iterator()
plus d'une fois donnera des résultats inattendus. La réponse ci-dessus devient alorsIterator<Element> iterator = createIterator();
List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
Vous pouvez également utiliser à IteratorUtils
partir d'Apache commons-collections , bien qu'il ne prenne pas en charge les génériques:
List list = IteratorUtils.toList(iterator);
Solution assez concise avec Java 8 simple en 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)
);
}
iterator.forEachRemaining( list::add )
, également nouveau dans Java 8, est beaucoup plus concis. Pousser la variable de liste dans Collector
n'améliore pas la lisibilité dans ce cas, car elle doit être prise en charge par a Stream
et a Spliterator
.
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
Essayez StickyList
avec Cactoos :
List<String> list = new StickyList<>(iterable);
Avertissement: je suis l'un des développeurs.
Iterable
! =Iterator
Je veux juste souligner une solution apparemment évidente qui ne sera PAS fonctionnera :
Liste liste = Stream.generate (itérateur :: suivant) .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 lance NoSuchElementException
(c'est ce queIterator#next()
qui fera à la fin).
La réponse du xehpuk doit être utilisée à la place si la méthode Iterator → Stream → List est votre choix.
utilisez google guava !
Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);
++
Ici, dans ce cas, si vous voulez le moyen le plus rapide possible, for loop
c'est mieux.
L'itérateur sur une taille d'échantillon de 10,000 runs
prises 40 ms
où comme pour les boucles2 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));
Cela suppose que la liste contient des chaînes.
for
boucle et accéder aux éléments d'une liste get(i)
est plus rapide que d'utiliser un itérateur ... mais ce n'est pas ce que le PO demandait, il a spécifiquement mentionné qu'un itérateur est donné en entrée.
get(int)
boucle, vous ne regardez que 100k des entrées de 1m. Si vous changez cette boucle pour être, it.size()
vous verrez que ces 2 méthodes sont proches de la même vitesse. En général, ces types de tests de vitesse java fournissent des informations limitées sur les performances réelles et doivent être examinés avec scepticisme.