Antworten:
Verwenden Sie besser eine Bibliothek wie Guava :
import com.google.common.collect.Lists;
Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
Ein weiteres Guaven-Beispiel:
ImmutableList.copyOf(myIterator);
oder Apache Commons Sammlungen :
import org.apache.commons.collections.IteratorUtils;
Iterator<Element> myIterator = ...//some iterator
List<Element> myList = IteratorUtils.toList(myIterator);
In Java 8 können Sie die neue forEachRemainingMethode verwenden, die der IteratorBenutzeroberfläche hinzugefügt wurde :
List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
::? Welchen Namen hat es? scheint ein direkter Verweis auf list.add () zu sein; und scheint auch etwas Java8 Neues zu sein; und danke! :)
::Syntax ist neu in Java 8 und bezieht sich auf eine "Methodenreferenz", bei der es sich um eine Kurzform eines Lambda handelt. Weitere Informationen finden Sie hier: docs.oracle.com/javase/tutorial/java/javaOO/…
iteratordas es ist ein ungelöstes Symbol
iterator.
Sie können einen Iterator wie folgt in eine neue Liste kopieren:
Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
copy.add(iter.next());
Dies setzt voraus, dass die Liste Zeichenfolgen enthält. Es gibt wirklich keinen schnelleren Weg, eine Liste aus einem Iterator neu zu erstellen. Sie müssen sie nicht mehr manuell durchlaufen und jedes Element in eine neue Liste des entsprechenden Typs kopieren.
EDIT:
Hier ist eine generische Methode zum typsicheren Kopieren eines Iterators in eine neue Liste:
public static <T> List<T> copyIterator(Iterator<T> iter) {
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
Verwenden Sie es so:
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]
Beachten Sie, dass zwischen Iterableund ein Unterschied besteht Iterator.
Wenn Sie eine haben Iterable, können Sie mit Java 8 diese Lösung verwenden:
Iterable<Element> iterable = createIterable();
List<Element> array = StreamSupport
.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
Wie ich weiß, Collectors.toList()schafft ArrayListInstanz.
Eigentlich sieht es meiner Meinung nach auch in einer Zeile gut aus.
Zum Beispiel, wenn Sie List<Element>von einer Methode zurückkehren müssen:
return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Iterable iterator. Sie sind völlig anders.
Iteratorzurück zu einem einmaligen Gebrauch Iterable durch Verwendung () -> iterator. Dies kann in solchen Situationen nützlich sein, aber lassen Sie mich noch einmal das Wichtige betonen: Sie können diese Methode nur verwenden, wenn eine einmalige Verwendung Iterable akzeptabel ist. Wenn Sie iterable.iterator()mehr als einmal anrufen , erhalten Sie unerwartete Ergebnisse. Die obige Antwort wird dannIterator<Element> iterator = createIterator(); List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
Sie können auch IteratorUtilsaus Apache Commons-Sammlungen verwenden , obwohl es keine Generika unterstützt:
List list = IteratorUtils.toList(iterator);
Ziemlich prägnante Lösung mit einfachem Java 8 unter Verwendung von 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 ), auch neu in Java 8, ist viel prägnanter. Das CollectorVerschieben der Listenvariablen in verbessert die Lesbarkeit in diesem Fall nicht, da sie von a Streamund a unterstützt werden muss Spliterator.
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
Versuchen StickyListvon Cactoos :
List<String> list = new StickyList<>(iterable);
Haftungsausschluss: Ich bin einer der Entwickler.
Iterable! =Iterator
Ich möchte nur auf eine scheinbar offensichtliche Lösung hinweisen, die NICHT funktioniert:
List list = Stream.generate (iterator :: next) .collect (Collectors.toList ());
Das liegt daran, Stream#generate(Supplier<T>)dass nur unendliche Streams erstellt werden können und nicht erwartet wird, NoSuchElementExceptiondass das Argument ausgelöst wird (das Iterator#next()wird am Ende der Fall sein ).
Die Antwort des xehpuk sollte stattdessen verwendet werden, wenn Sie den Iterator → Stream → List-Weg wählen .
benutze Google Guave !
Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);
++
Hier in diesem Fall for loopist es besser, wenn Sie den schnellstmöglichen Weg wollen .
Der Iterator über eine Stichprobengröße von 10,000 runsTakes, 40 mswie für Schleifen-Takes2 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));
Dies setzt voraus, dass die Liste Zeichenfolgen enthält.
forSchleife und der Zugriff auf die Elemente einer Liste mit get(i)schneller als die Verwendung eines Iterators ... aber das hat das OP nicht verlangt, er erwähnte ausdrücklich, dass ein Iterator als Eingabe angegeben wird.
get(int)Schleife sehen Sie nur 100.000 der 1-Meter-Einträge. Wenn Sie diese Schleife in ändern, werden it.size()Sie feststellen, dass diese beiden Methoden nahe an der gleichen Geschwindigkeit liegen. Im Allgemeinen liefern diese Arten von Java-Geschwindigkeitstests nur begrenzte Informationen zur tatsächlichen Leistung und sollten skeptisch betrachtet werden.