Étant donné Iterator<Element>
, comment pouvons - nous le convertir Iterator
à ArrayList<Element>
(ou List<Element>
) dans le meilleur et le plus rapide façon possible, afin que nous puissions utiliser les ArrayList
opérations de sur elle, comme get(index)
, add(element)
, etc.
241
Dans Java 8, vous pouvez utiliser la nouvelle
forEachRemaining
méthode qui a été ajoutée à l'Iterator
interface:la source
::
? 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ésoluiterator
.Vous pouvez copier un itérateur dans une nouvelle liste comme celle-ci:
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:
Utilisez-le comme ceci:
la source
Notez qu'il y a une différence entre
Iterable
etIterator
.Si vous en avez un
Iterable
, alors avec Java 8, vous pouvez utiliser cette solution:Comme je sais,
Collectors.toList()
crée uneArrayList
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:la source
Iterable
iterator
. Ils sont complètement différents.Iterator
dos en une seule utilisationIterable
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 utilisationIterable
est acceptable. Appeleriterable.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:la source
Solution assez concise avec Java 8 simple en utilisant
java.util.stream
:la source
iterator.forEachRemaining( list::add )
, également nouveau dans Java 8, est beaucoup plus concis. Pousser la variable de liste dansCollector
n'améliore pas la lisibilité dans ce cas, car elle doit être prise en charge par aStream
et aSpliterator
.la source
Essayez
StickyList
avec Cactoos :Avertissement: je suis l'un des développeurs.
la source
Iterable
! =Iterator
Voici une ligne à l'aide de Streams
la source
Je veux juste souligner une solution apparemment évidente qui ne sera PAS fonctionnera :
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 lanceNoSuchElementException
(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.
la source
utilisez google guava !
++
la source
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
prises40 ms
où comme pour les boucles2 ms
Cela suppose que la liste contient des chaînes.
la source
for
boucle et accéder aux éléments d'une listeget(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.