Mengingat Iterator<Element>
, bagaimana kita dapat mengkonversi Iterator
ke ArrayList<Element>
(atau List<Element>
) di terbaik dan tercepat cara yang mungkin, sehingga kita dapat menggunakan ArrayList
's operasi di atasnya seperti get(index)
, add(element)
, dll
241
Di Java 8, Anda dapat menggunakan
forEachRemaining
metode baru yang telah ditambahkan keIterator
antarmuka:sumber
::
? nama apa itu? tampaknya referensi langsung ke list.add (); dan sepertinya juga beberapa hal baru java8; dan terimakasih! :)::
Sintaksnya baru di Java 8, dan mengacu pada "referensi metode," yang merupakan bentuk singkatan dari lambda. Lihat di sini untuk info lebih lanjut: docs.oracle.com/javase/tutorial/java/javaOO/…iterator
datangnya itu adalah simbol yang belum terselesaikaniterator
.Anda dapat menyalin iterator ke daftar baru seperti ini:
Itu dengan asumsi bahwa daftar tersebut berisi string. Sebenarnya tidak ada cara yang lebih cepat untuk membuat ulang daftar dari iterator, Anda terjebak dengan melewatinya dengan tangan dan menyalin setiap elemen ke daftar baru dari jenis yang sesuai.
EDIT:
Berikut adalah metode umum untuk menyalin iterator ke daftar baru dengan cara yang aman:
Gunakan seperti ini:
sumber
Perhatikan ada perbedaan antara
Iterable
danIterator
.Jika Anda memiliki
Iterable
, maka dengan Java 8 Anda dapat menggunakan solusi ini:Seperti yang saya tahu
Collectors.toList()
menciptakanArrayList
instance.Sebenarnya menurut saya, itu juga terlihat bagus dalam satu baris.
Misalnya jika Anda perlu kembali
List<Element>
dari beberapa metode:sumber
Iterable
iterator
. Mereka benar-benar berbeda.Iterator
kembali ke satu penggunaanIterable
dengan menggunakan() -> iterator
. Ini bisa berguna dalam situasi seperti ini, tetapi izinkan saya menekankan hal yang penting lagi: Anda dapat menggunakan metode ini hanya jika satu penggunaanIterable
dapat diterima. Memanggiliterable.iterator()
lebih dari satu kali akan menghasilkan hasil yang tidak terduga. Jawaban di atas kemudian menjadiIterator<Element> iterator = createIterator();
List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
Anda juga dapat menggunakan
IteratorUtils
dari kumpulan commons Apache , meskipun tidak mendukung obat generik:sumber
Solusi ringkas dengan Java 8 sederhana menggunakan
java.util.stream
:sumber
iterator.forEachRemaining( list::add )
, juga baru di Java 8, jauh lebih ringkas. Mendorong variabel daftar keCollector
tidak meningkatkan readibility dalam hal ini, karena harus didukung oleh aStream
dan aSpliterator
.sumber
Coba
StickyList
dari Cactoos :Penafian: Saya salah satu pengembang.
sumber
Iterable
! =Iterator
Berikut ini adalah one-liner menggunakan Streams
sumber
Saya hanya ingin menunjukkan solusi yang tampaknya jelas yang TIDAK akan berhasil:
Itu karena
Stream#generate(Supplier<T>)
hanya dapat membuat aliran tanpa batas, ia tidak mengharapkan argumennya untuk dibuangNoSuchElementException
(itulah yangIterator#next()
akan dilakukan pada akhirnya).Jawaban xehpuk seharusnya digunakan jika Iterator → Stream → Cara daftar adalah pilihan Anda.
sumber
gunakan google jambu !
++
sumber
Di sini dalam hal ini jika Anda ingin cara tercepat mungkin
for loop
lebih baik.Iterator di atas ukuran sampel
10,000 runs
membutuhkan40 ms
tempat untuk loop2 ms
Itu dengan asumsi bahwa daftar tersebut berisi string.
sumber
for
loop dan mengakses elemen daftar denganget(i)
lebih cepat daripada menggunakan iterator ... tapi bukan itu yang ditanyakan OP, ia secara khusus menyebutkan bahwa iterator diberikan sebagai input.get(int)
loop Anda hanya melihat 100k dari entri 1m. Jika Anda mengubah loop itu menjadiit.size()
Anda akan melihat bahwa 2 metode ini dekat dengan kecepatan yang sama. Secara umum tes kecepatan java semacam ini memberikan informasi kinerja kehidupan nyata yang terbatas dan harus dilihat secara skeptis.