जवाबों:
अमरूद जैसे पुस्तकालय का बेहतर उपयोग करें :
import com.google.common.collect.Lists;
Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
एक और अमरूद का उदाहरण:
ImmutableList.copyOf(myIterator);
या अपाचे कॉमन्स संग्रह :
import org.apache.commons.collections.IteratorUtils;
Iterator<Element> myIterator = ...//some iterator
List<Element> myList = IteratorUtils.toList(myIterator);
जावा 8 में, आप इंटरफ़ेस forEachRemainingमें जोड़ी गई नई विधि का उपयोग कर सकते हैं Iterator:
List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
::? इसका क्या नाम है? list.add () के लिए एक सीधा संदर्भ लगता है; और कुछ java8 नई बात भी लगती है; और धन्यवाद! :)
::जावा 8 में वाक्यविन्यास नया है, और यह एक "विधि संदर्भ" को संदर्भित करता है, जो कि लंबोदर का संक्षिप्त रूप है। अधिक जानकारी के लिए यहां देखें: docs.oracle.com/javase/tutorial/java/javaOO/…
iteratorआ रहा है यह एक अनसुलझे प्रतीक है
iterator।
आप इस तरह से एक नई सूची में एक पुनरावृत्त कॉपी कर सकते हैं:
Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
copy.add(iter.next());
यह मानते हुए कि सूची में तार हैं। वास्तव में एक पुनरावृत्त से एक सूची को फिर से बनाने का एक तेज़ तरीका नहीं है, आप इसे हाथ से ट्रेस करने और प्रत्येक तत्व को उपयुक्त प्रकार की नई सूची में कॉपी करने के साथ फंस गए हैं।
संपादित करें:
एक प्रकार से सुरक्षित तरीके से एक नई सूची में एक पुनरावृत्ति की प्रतिलिपि बनाने के लिए यहां एक सामान्य विधि है:
public static <T> List<T> copyIterator(Iterator<T> iter) {
List<T> copy = new ArrayList<T>();
while (iter.hasNext())
copy.add(iter.next());
return copy;
}
इसे इस तरह उपयोग करें:
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]
ध्यान दें कि Iterableऔर के बीच अंतर है Iterator।
यदि आपके पास एक है Iterable, तो जावा 8 के साथ आप इस समाधान का उपयोग कर सकते हैं:
Iterable<Element> iterable = createIterable();
List<Element> array = StreamSupport
.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
जैसा कि मुझे पता Collectors.toList()है कि ArrayListउदाहरण बनता है ।
वास्तव में मेरी राय में, यह एक पंक्ति में भी अच्छा लगता है।
उदाहरण के लिए यदि आपको List<Element>किसी विधि से लौटने की आवश्यकता है :
return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Iterable iterator। वे पूरी तरह से अलग हैं।
Iteratorबैक का उपयोग Iterable करके परिवर्तित कर सकते हैं () -> iterator। यह इस तरह की स्थितियों में उपयोगी हो सकता है, लेकिन मुझे फिर से महत्वपूर्ण बात पर जोर देने दें: आप इस पद्धति का उपयोग केवल तभी कर सकते हैं जब कोई एकल उपयोग Iterable स्वीकार्य हो। iterable.iterator()एक से अधिक बार कॉल करने पर अप्रत्याशित परिणाम मिलेंगे। उपरोक्त उत्तर तब बनता हैIterator<Element> iterator = createIterator(); List<Element> array = StreamSupport.stream(((Iterable<Element>) () -> iterable).spliterator(), false).collect(toList());
आप IteratorUtilsअपाचे कॉमन्स-संग्रह से भी उपयोग कर सकते हैं , हालांकि यह जेनरिक का समर्थन नहीं करता है:
List list = IteratorUtils.toList(iterator);
सादे जावा 8 का उपयोग करके सुंदर संक्षिप्त समाधान 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 ), जावा 8 में भी नया, बहुत अधिक संक्षिप्त है। सूची चर को धक्का देना Collectorइस मामले में पठनीयता में सुधार नहीं करता है, क्योंकि इसे ए Streamऔर ए द्वारा समर्थित किया जाना है Spliterator।
List result = new ArrayList();
while (i.hasNext()){
result.add(i.next());
}
मैं सिर्फ एक स्पष्ट रूप से स्पष्ट समाधान को इंगित करना चाहता हूं जो काम नहीं करेगा :
सूची सूची = Stream.generate (पुनरावृति :: अगला) .collect (Collectors.toList ());
ऐसा इसलिए है क्योंकि यह Stream#generate(Supplier<T>)केवल अनंत धाराएँ बना सकता है, यह इसके तर्क को फेंकने की उम्मीद नहीं करता है NoSuchElementException(यह Iterator#next()अंत में क्या करेगा)।
Xehpuk के उत्तर का उपयोग इसके बजाय किया जाना चाहिए यदि Iterator → स्ट्रीम → सूची तरीका आपकी पसंद है।
Google अमरूद का उपयोग करें !
Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);
++
यहां इस मामले में अगर आप सबसे तेज तरीका चाहते हैं तो for loopबेहतर है।
लूप के लिए जहां 10,000 runsले जाता है के एक नमूने के आकार पर चलनेवाला40 ms2 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));
यह मानते हुए कि सूची में तार हैं।
forलूप का उपयोग करना और एक सूची के तत्वों के साथ पहुंच बनाना एक get(i)इट्रेटर का उपयोग करने की तुलना में तेज है ... लेकिन यह वह नहीं है जो ओपी पूछ रहा था, उन्होंने विशेष रूप से उल्लेख किया है कि एक इटरेटर इनपुट के रूप में दिया गया है।
get(int)पाश आप केवल 1 मी प्रविष्टियों की 100k देख रहे हैं। यदि आप उस लूप को बदल देते हैं तो आप it.size()देखेंगे कि ये 2 विधियाँ समान गति के करीब हैं। सामान्य तौर पर इन प्रकार के जावा गति परीक्षण सीमित वास्तविक जीवन प्रदर्शन की जानकारी प्रदान करते हैं और इस पर संदेह की दृष्टि से देखा जाना चाहिए।