Biorąc pod uwagę Iterator<Element>
, w jaki sposób możemy przekonwertować Iterator
do ArrayList<Element>
(lub List<Element>
) w najlepszym i najszybszym sposobem możliwe, tak, że możemy użyć ArrayList
„s operacje na takich jak on get(index)
, add(element)
itp
241
W Javie 8 możesz użyć nowej
forEachRemaining
metody dodanej doIterator
interfejsu:źródło
::
? jakie to ma imię wydaje się bezpośrednim odniesieniem do list.add (); i wydaje się też, że jest coś nowego w java8; i dzięki! :)::
Składnia jest nowa w Javie 8 i odnosi się do „odwołania do metody”, które jest skrótową formą lambda. Zobacz tutaj, aby uzyskać więcej informacji: docs.oracle.com/javase/tutorial/java/javaOO/…iterator
pochodzi? jest to nierozwiązany symboliterator
.Możesz skopiować iterator do nowej listy, takiej jak ta:
Zakłada się, że lista zawiera ciągi znaków. Naprawdę nie ma szybszego sposobu na odtworzenie listy z iteratora, utkniesz w ręcznym przechodzeniu do niej i kopiowaniu każdego elementu na nową listę odpowiedniego typu.
EDYTOWAĆ :
Oto ogólna metoda kopiowania iteratora na nową listę w sposób bezpieczny dla typu:
Użyj tego w ten sposób:
źródło
Uwaga: istnieje różnica między
Iterable
iIterator
.Jeśli masz
Iterable
, to w Javie 8 możesz użyć tego rozwiązania:Jak wiem
Collectors.toList()
tworzyArrayList
instancję.Moim zdaniem w jednym wierszu wygląda dobrze.
Na przykład, jeśli chcesz wrócić
List<Element>
z jakiejś metody:źródło
Iterable
iterator
. Oni są zupełnie inni.Iterator
powrót do pojedynczego użyciaIterable
za pomocą() -> iterator
. Może to być przydatne w takich sytuacjach, ale pozwólcie, że jeszcze raz podkreślę ważną rzecz: Możesz użyć tej metody tylko wtedy, gdy jedno użycieIterable
jest dopuszczalne. Dzwonienieiterable.iterator()
więcej niż raz da nieoczekiwane rezultaty. Powyższa odpowiedź staje sięIterator<Element> iterator = createIterator();
List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
Możesz także korzystać
IteratorUtils
z wspólnych zbiorów Apache , chociaż nie obsługuje on ogólnych:źródło
Całkiem zwięzłe rozwiązanie z prostym Java 8 za pomocą
java.util.stream
:źródło
iterator.forEachRemaining( list::add )
także nowy w Javie 8 jest o wiele bardziej zwięzły.Collector
Wepchnięcie zmiennej listy do nie poprawia czytelności w tym przypadku, ponieważ musi być obsługiwana przez aStream
i aSpliterator
.źródło
Spróbuj
StickyList
z Cactoos :Oświadczenie: Jestem jednym z programistów.
źródło
Iterable
! =Iterator
Oto linijka korzystająca ze strumieni
źródło
Chcę tylko wskazać na pozornie oczywiste rozwiązanie, które NIE zadziała:
To dlatego, że
Stream#generate(Supplier<T>)
może tworzyć tylko nieskończone strumienie, nie spodziewa się, że jego argument zostanie rzuconyNoSuchElementException
(toIterator#next()
zrobi w końcu).Zamiast tego należy użyć odpowiedzi xehpuk, jeśli Twój wybór to Iterator → Strumień → Lista.
źródło
użyj google guava !
++
źródło
Tutaj w tym przypadku, jeśli chcesz najszybszy możliwy sposób,
for loop
to lepiej.Iterator na próbce wielkości
10,000 runs
ujęć,40 ms
gdzie dla ujęć pętli2 ms
Zakłada się, że lista zawiera ciągi znaków.
źródło
for
pętli i uzyskiwanie dostępu do elementów listyget(i)
jest szybsze niż używanie iteratora ... ale nie o to prosił OP, szczególnie wspomniał, że iterator jest podawany jako dane wejściowe.get(int)
pętli patrzysz tylko na 100 000 wpisów o długości 1 m. Jeśli zmienisz tę pętlęit.size()
, zobaczysz, że te 2 metody są zbliżone do tej samej prędkości. Ogólnie rzecz biorąc, tego rodzaju testy prędkości java dostarczają ograniczonych informacji na temat rzeczywistych wyników i należy na nie spojrzeć sceptycznie.