Ein Iterator entspricht nicht unbedingt etwas mit einer "Zählung" ...
Oliver Charlesworth
Iteratoren sind was sie sind; Um zum nächsten Objekt einer Sammlung zu iterieren (es kann sich um Set, Array usw. handeln). Warum müssen sie die Größe angeben, wenn es ihnen egal ist, wofür sie iterieren möchten? to provide an implementation-independent method for access, in which the user does not need to know whether the underlying implementation is some form of array or of linked list, and allows the user go through the collection without explicit indexing.penguin.ewu.edu/~trolfe/LinkedSort/Iterator.html
Ecle
Antworten:
67
Wenn Sie nur den Iterator haben, müssen Sie dies tun - er weiß nicht , wie viele Elemente noch durchlaufen werden müssen, sodass Sie ihn nicht nach diesem Ergebnis abfragen können. Es gibt Dienstprogrammmethoden, die dies zu tun scheinen (wie Iterators.size()in Guava), aber darunter führen sie nur ungefähr den gleichen Vorgang aus.
Viele Iteratoren stammen jedoch aus Sammlungen, deren Größe Sie häufig abfragen können. Wenn es sich um eine benutzerdefinierte Klasse handelt, für die Sie den Iterator erhalten, können Sie eine size () -Methode für diese Klasse bereitstellen.
Kurz gesagt, in einer Situation, in der Sie nur den Iterator haben, gibt es keinen besseren Weg, aber häufig haben Sie Zugriff auf die zugrunde liegende Sammlung oder das zugrunde liegende Objekt, von dem Sie möglicherweise die Größe direkt abrufen können.
Wenn Sie nur den Iterator haben, gibt es keinen "besseren" Weg. Wenn der Iterator aus einer Sammlung stammt, können Sie dies als Größe angeben.
Denken Sie daran, dass Iterator nur eine Schnittstelle zum Durchlaufen bestimmter Werte ist. Sie hätten sehr gut Code wie diesen
newIterator<Long>(){finalRandom r =newRandom();@Overridepublicboolean hasNext(){returntrue;}@OverridepublicLong next(){return r.nextLong();}@Overridepublicvoid remove(){thrownewIllegalArgumentException("Not implemented");}};
oder
newIterator<BigInteger>(){BigInteger next =BigInteger.ZERO;@Overridepublicboolean hasNext(){returntrue;}@OverridepublicBigInteger next(){BigInteger current = next;
next = next.add(BigInteger.ONE);return current;}@Overridepublicvoid remove(){thrownewIllegalArgumentException("Not implemented");}};
Bei Verwendung der Guava-Bibliothek besteht eine weitere Option darin, die Iterablein eine zu konvertieren List.
List list =Lists.newArrayList(some_iterator);int count = list.size();
Verwenden Sie diese Option, wenn Sie nach dem Abrufen der Größe auch auf die Elemente des Iterators zugreifen müssen. Durch die Verwendung können Iterators.size()Sie nicht mehr auf die iterierten Elemente zugreifen.
@ LoveToCode Weniger effizient als das Beispiel auf der ursprünglichen Frage
Winter
2
Sicher, das Erstellen eines neuen Objekts mit allen Elementen ist langsamer als nur das Iterieren und Verwerfen. IMHO ist diese Lösung ein Einzeiler, der die Lesbarkeit des Codes verbessert. Ich benutze es oft für Sammlungen mit wenigen Elementen (bis zu 1000) oder wenn Geschwindigkeit kein Problem ist.
Tashuhka
4
Es gibt keinen effizienteren Weg, wenn Sie nur den Iterator haben. Und wenn der Iterator nur einmal verwendet werden kann, ist es ... problematisch, die Anzahl zu ermitteln, bevor Sie den Inhalt des Iterators erhalten.
Die Lösung besteht entweder darin, Ihre Anwendung so zu ändern, dass sie nicht gezählt werden muss, oder die Zählung auf andere Weise zu erhalten. (Übergeben Sie zum Beispiel ein Collectionanstatt Iterator...)
Das Iteratorobjekt enthält die gleiche Anzahl von Elementen wie Ihre Sammlung.
List<E> a =...;Iterator<E> i = a.iterator();int size = a.size();//Because iterators size is equal to list a's size.
Anstatt die Größe des Iterators zu ermitteln und den Index 0 auf diese Größe zu durchlaufen, ist es besser, die Methode next () des Iterators zu durchlaufen .
to provide an implementation-independent method for access, in which the user does not need to know whether the underlying implementation is some form of array or of linked list, and allows the user go through the collection without explicit indexing.
penguin.ewu.edu/~trolfe/LinkedSort/Iterator.htmlAntworten:
Wenn Sie nur den Iterator haben, müssen Sie dies tun - er weiß nicht , wie viele Elemente noch durchlaufen werden müssen, sodass Sie ihn nicht nach diesem Ergebnis abfragen können. Es gibt Dienstprogrammmethoden, die dies zu tun scheinen (wie
Iterators.size()
in Guava), aber darunter führen sie nur ungefähr den gleichen Vorgang aus.Viele Iteratoren stammen jedoch aus Sammlungen, deren Größe Sie häufig abfragen können. Wenn es sich um eine benutzerdefinierte Klasse handelt, für die Sie den Iterator erhalten, können Sie eine size () -Methode für diese Klasse bereitstellen.
Kurz gesagt, in einer Situation, in der Sie nur den Iterator haben, gibt es keinen besseren Weg, aber häufig haben Sie Zugriff auf die zugrunde liegende Sammlung oder das zugrunde liegende Objekt, von dem Sie möglicherweise die Größe direkt abrufen können.
quelle
Verwenden der Guavenbibliothek :
Intern iteriert es nur über alle Elemente, so dass es nur der Einfachheit halber ist.
quelle
Ihr Code gibt Ihnen eine Ausnahme, wenn Sie das Ende des Iterators erreichen. Du könntest es tun:
Wenn Sie Zugriff auf die zugrunde liegende Sammlung hätten, könnten Sie
coll.size()
...BEARBEITEN OK Sie haben geändert ...
quelle
Sie müssen immer iterieren. Sie können jedoch Java 8, 9 verwenden, um das Zählen durchzuführen, ohne explizit eine Schleife durchzuführen:
Hier ist ein Test:
Dies druckt:
Interessanterweise können Sie die Zähloperation hier parallelisieren, indem Sie das
parallel
Flag bei diesem Aufruf ändern :quelle
Wenn Sie nur den Iterator haben, gibt es keinen "besseren" Weg. Wenn der Iterator aus einer Sammlung stammt, können Sie dies als Größe angeben.
Denken Sie daran, dass Iterator nur eine Schnittstelle zum Durchlaufen bestimmter Werte ist. Sie hätten sehr gut Code wie diesen
oder
quelle
Bei Verwendung der Guava-Bibliothek besteht eine weitere Option darin, die
Iterable
in eine zu konvertierenList
.Verwenden Sie diese Option, wenn Sie nach dem Abrufen der Größe auch auf die Elemente des Iterators zugreifen müssen. Durch die Verwendung können
Iterators.size()
Sie nicht mehr auf die iterierten Elemente zugreifen.quelle
Es gibt keinen effizienteren Weg, wenn Sie nur den Iterator haben. Und wenn der Iterator nur einmal verwendet werden kann, ist es ... problematisch, die Anzahl zu ermitteln, bevor Sie den Inhalt des Iterators erhalten.
Die Lösung besteht entweder darin, Ihre Anwendung so zu ändern, dass sie nicht gezählt werden muss, oder die Zählung auf andere Weise zu erhalten. (Übergeben Sie zum Beispiel ein
Collection
anstattIterator
...)quelle
für Java 8 könnten Sie verwenden,
quelle
Das Iteratorobjekt enthält die gleiche Anzahl von Elementen wie Ihre Sammlung.
Anstatt die Größe des Iterators zu ermitteln und den Index 0 auf diese Größe zu durchlaufen, ist es besser, die Methode next () des Iterators zu durchlaufen .
quelle
a
, sondern nuri
?