Yanıtlar:
Guava gibi bir kütüphaneyi daha iyi kullanın :
import com.google.common.collect.Lists;
Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
Başka bir Guava örneği:
ImmutableList.copyOf(myIterator);
veya Apache Commons Koleksiyonları :
import org.apache.commons.collections.IteratorUtils;
Iterator<Element> myIterator = ...//some iterator
List<Element> myList = IteratorUtils.toList(myIterator);
Java 8'de, arabirime forEachRemainingeklenen yeni yöntemi kullanabilirsiniz Iterator:
List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
::? hangi adı var? list.add () öğesine doğrudan bir başvuru gibi görünüyor; ve java8 yeni bir şey gibi görünüyor; ve teşekkürler! :)
::Sözdizimi Java 8'de yenidir ve lambda'nın kestirme bir biçimi olan bir "yöntem başvurusu" anlamına gelir. Daha fazla bilgi için buraya bakın: docs.oracle.com/javase/tutorial/java/javaOO/…
iteratorgeliyor çözülmemiş bir semboldür
iterator.
Bir yineleyiciyi aşağıdaki gibi yeni bir listeye kopyalayabilirsiniz:
Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
copy.add(iter.next());
Bu, listenin dize içerdiğini varsayar. Bir listeyi bir yineleyiciden yeniden oluşturmanın daha hızlı bir yolu yoktur, elle gezdirmek ve her bir öğeyi uygun türden yeni bir listeye kopyalamak zorunda kalırsınız.
DÜZENLE :
Aşağıda, yineleyiciyi yeni bir listeye güvenli bir şekilde kopyalamak için genel bir yöntem verilmiştir:
public static <T> List<T> copyIterator(Iterator<T> iter) {
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
Şöyle kullanın:
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]
IterableVe arasında bir fark olduğunu unutmayın Iterator.
Bir paranız varsa Iterable, Java 8 ile bu çözümü kullanabilirsiniz:
Iterable<Element> iterable = createIterable();
List<Element> array = StreamSupport
.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
Bildiğim gibi örnek Collectors.toList()oluşturur ArrayList.
Aslında bence, bir satırda da iyi görünüyor.
Örneğin List<Element>, bazı yöntemlerden geri dönmeniz gerekiyorsa :
return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Iterable iterator. Bunlar tamamen farklı.
Iteratorbir karşı arkasını tek kullanım Iterable kullanarak () -> iterator. Bu, bu gibi durumlarda yararlı olabilir, ancak önemli şeyi tekrar vurgulamama izin verin: Bu yöntemi yalnızca tek bir kullanım Iterable kabul edilebilirse kullanabilirsiniz . iterable.iterator()Birden fazla çağrı yapmak beklenmedik sonuçlar verecektir. Yukarıdaki cevap daha sonraIterator<Element> iterator = createIterator(); List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
Ayrıca jenerikleri desteklemese de IteratorUtilsApache ortak koleksiyonlarından da kullanabilirsiniz :
List list = IteratorUtils.toList(iterator);
Sade Java 8 ile oldukça özlü bir çözüm 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 )Java 8'de de yeni olanların çok daha özlü olduğunu söyleyebilirim . Liste değişkeninin içine Collectoritilmesi, a Streamve a tarafından desteklenmesi gerektiğinden, bu durumda okunabilirliği artırmaz Spliterator.
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
Deneyin StickyListgelen Cactoos :
List<String> list = new StickyList<>(iterable);
Feragatname: Geliştiricilerden biriyim.
Iterable! =Iterator
Sadece bariz görünen bir çözüm işaret etmek istiyorum DEĞİL olacaktır çalışır:
Liste listesi = Stream.generate (iterator :: next) .Yağlar (Collectors.toList ());
Çünkü Stream#generate(Supplier<T>)sadece sonsuz akışlar yaratabilir, argümanının atmasını beklemez NoSuchElementException( Iterator#next()sonunda yapacak olan budur).
Eğer Iterator → Akış → Liste yolu seçiminizse xehpuk'un cevabı kullanılmalıdır.
google guava kullanın !
Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);
++
Burada bu durumda mümkün olan en hızlı yolu istiyorsanız o zaman for loopdaha iyidir.
Bir numune sayısı üzerinden yineleyici 10,000 runsalır 40 msdöngü alır için gibi olduğu2 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));
Bu, listenin dize içerdiğini varsayar.
fordöngü kullanmak ve bir listenin öğelerine erişmek get(i)bir yineleyici kullanmaktan daha hızlıdır ... ancak OP'nin istediği bu değildi, özellikle bir yineleyicinin girdi olarak verildiğini belirtti .
get(int)döngü yalnızca 1m girişlerinin 100k bakıyoruz. Bu döngüyü değiştirirseniz, it.size()bu 2 yöntemin aynı hıza yakın olduğunu görürsünüz. Genel olarak bu tür java hız testleri sınırlı gerçek yaşam performansı bilgileri sağlar ve şüpheyle bakılmalıdır.