Jawaban:
Lebih baik gunakan perpustakaan seperti Jambu :
import com.google.common.collect.Lists;
Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
Contoh lain Jambu Biji:
ImmutableList.copyOf(myIterator);
atau Koleksi Apache Commons :
import org.apache.commons.collections.IteratorUtils;
Iterator<Element> myIterator = ...//some iterator
List<Element> myList = IteratorUtils.toList(myIterator);
Di Java 8, Anda dapat menggunakan forEachRemaining
metode baru yang telah ditambahkan ke Iterator
antarmuka:
List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
::
? 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 terselesaikan
iterator
.
Anda dapat menyalin iterator ke daftar baru seperti ini:
Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
copy.add(iter.next());
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:
public static <T> List<T> copyIterator(Iterator<T> iter) {
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
Gunakan seperti ini:
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]
Perhatikan ada perbedaan antara Iterable
dan Iterator
.
Jika Anda memiliki Iterable
, maka dengan Java 8 Anda dapat menggunakan solusi ini:
Iterable<Element> iterable = createIterable();
List<Element> array = StreamSupport
.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
Seperti yang saya tahu Collectors.toList()
menciptakan ArrayList
instance.
Sebenarnya menurut saya, itu juga terlihat bagus dalam satu baris.
Misalnya jika Anda perlu kembali List<Element>
dari beberapa metode:
return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Iterable
iterator
. Mereka benar-benar berbeda.
Iterator
kembali ke satu penggunaan Iterable
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 penggunaan Iterable
dapat diterima. Memanggil iterable.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:
List list = IteratorUtils.toList(iterator);
Solusi ringkas dengan Java 8 sederhana menggunakan 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 )
, juga baru di Java 8, jauh lebih ringkas. Mendorong variabel daftar ke Collector
tidak meningkatkan readibility dalam hal ini, karena harus didukung oleh a Stream
dan a Spliterator
.
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
Saya hanya ingin menunjukkan solusi yang tampaknya jelas yang TIDAK akan berhasil:
Daftar daftar = Stream.generate (iterator :: next) .collect (Collectors.toList ());
Itu karena Stream#generate(Supplier<T>)
hanya dapat membuat aliran tanpa batas, ia tidak mengharapkan argumennya untuk dibuang NoSuchElementException
(itulah yang Iterator#next()
akan dilakukan pada akhirnya).
Jawaban xehpuk seharusnya digunakan jika Iterator → Stream → Cara daftar adalah pilihan Anda.
gunakan google jambu !
Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);
++
Di sini dalam hal ini jika Anda ingin cara tercepat mungkin for loop
lebih baik.
Iterator di atas ukuran sampel 10,000 runs
membutuhkan 40 ms
tempat untuk loop2 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));
Itu dengan asumsi bahwa daftar tersebut berisi string.
for
loop dan mengakses elemen daftar dengan get(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 menjadi it.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.