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 forEachRemainingmetode baru yang telah ditambahkan ke Iteratorantarmuka:
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/…
iteratordatangnya 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 Iterabledan 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 ArrayListinstance.
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.
Iteratorkembali 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 IteratorUtilsdari 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 Collectortidak meningkatkan readibility dalam hal ini, karena harus didukung oleh a Streamdan 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 looplebih baik.
Iterator di atas ukuran sampel 10,000 runsmembutuhkan 40 mstempat 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.
forloop 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.