क्या एक "कम्प्यूटेशनल" त्वरित रूप से एक पुनरावृत्त की गिनती प्राप्त करने का तरीका है?
int i = 0;
for ( ; some_iterator.hasNext() ; ++i ) some_iterator.next();
... सीपीयू चक्रों की बर्बादी की तरह लगता है।
क्या एक "कम्प्यूटेशनल" त्वरित रूप से एक पुनरावृत्त की गिनती प्राप्त करने का तरीका है?
int i = 0;
for ( ; some_iterator.hasNext() ; ++i ) some_iterator.next();
... सीपीयू चक्रों की बर्बादी की तरह लगता है।
to provide an implementation-independent method for access, in which the user does not need to know whether the underlying implementation is some form of array or of linked list, and allows the user go through the collection without explicit indexing.
p पेंगुइनin.ewu.edu/~trolfe/LinkedSort/Iterator.html
जवाबों:
यदि आपको बस पुनरावृति मिली है, तो आपको यही करना होगा - यह नहीं पता कि कितने आइटम्स को इटर्सेट पर छोड़ दिया गया है, इसलिए आप इसे उस परिणाम के लिए क्वेरी नहीं कर सकते। उपयोगिता विधियां हैं जो ऐसा करने के लिए प्रतीत होंगी (जैसे कि Iterators.size()
अमरूद में), लेकिन नीचे वे लगभग एक ही ऑपरेशन कर रहे हैं।
हालांकि, कई पुनरावृत्तियां संग्रह से आती हैं, जिन्हें आप अक्सर उनके आकार के लिए क्वेरी कर सकते हैं। और अगर यह एक उपयोगकर्ता द्वारा बनाया गया वर्ग है जिसके लिए आपको इटेटर मिल रहा है, तो आप उस वर्ग पर एक आकार () विधि प्रदान कर सकते हैं।
संक्षेप में, उस स्थिति में जहां आपके पास केवल इटरेटर है तो कोई बेहतर तरीका नहीं है, लेकिन बहुत अधिक बार आपके पास अंतर्निहित संग्रह या ऑब्जेक्ट तक पहुंच नहीं है, जिससे आप सीधे आकार प्राप्त करने में सक्षम हो सकते हैं।
Iterators.size(...)
(नीचे अन्य टिप्पणियों में और जावा-डॉक में उल्लेख किया गया है): "पुनरावृत्ति करने वाले तत्वों की संख्या लौटाता है। इटरेटर को छोड़ दिया जाएगा: इसकी hasNext () विधि झूठी हो जाएगी।" इसका मतलब है, आप बाद में अब Iterator का उपयोग नहीं कर सकते। Lists.newArrayList(some_iterator);
मदद कर सकता है।
अमरूद पुस्तकालय का उपयोग :
int size = Iterators.size(iterator);
आंतरिक रूप से यह सिर्फ सभी तत्वों पर निर्भर करता है इसलिए इसकी सुविधा के लिए।
जब आप पुनरावृत्ति के अंत तक पहुँचते हैं तो आपका कोड आपको एक अपवाद देगा। तुम यह कर सकते थे:
int i = 0;
while(iterator.hasNext()) {
i++;
iterator.next();
}
यदि आपके पास अंतर्निहित संग्रह तक पहुंच है, तो आप कॉल कर पाएंगे coll.size()
...
संपादित करें ठीक है आपने संशोधित किया है ...
आपको हमेशा इटरेट करना होगा। फिर भी आप जावा 8, 9 का उपयोग बिना खोज के लूपिंग के बिना गिनती करने के लिए कर सकते हैं:
Iterable<Integer> newIterable = () -> iter;
long count = StreamSupport.stream(newIterable.spliterator(), false).count();
यहाँ एक परीक्षण है:
public static void main(String[] args) throws IOException {
Iterator<Integer> iter = Arrays.asList(1, 2, 3, 4, 5).iterator();
Iterable<Integer> newIterable = () -> iter;
long count = StreamSupport.stream(newIterable.spliterator(), false).count();
System.out.println(count);
}
यह प्रिंट:
5
दिलचस्प है कि आप parallel
इस कॉल पर ध्वज को बदलकर यहां गिनती ऑपरेशन को समानांतर कर सकते हैं :
long count = StreamSupport.stream(newIterable.spliterator(), *true*).count();
अमरूद पुस्तकालय का उपयोग करते हुए , एक और विकल्प में परिवर्तित करने के Iterable
लिए है List
।
List list = Lists.newArrayList(some_iterator);
int count = list.size();
यदि इसका आकार मिलने के बाद आपको पुनरावृति के तत्वों को एक्सेस करने की आवश्यकता है, तो इसका उपयोग करें। Iterators.size()
आप का उपयोग करके अब iterated तत्वों तक पहुँच सकते हैं।
यदि आपके पास सभी इट्रेटर हैं, तो नहीं, कोई "बेहतर" तरीका नहीं है। यदि पुनरावृत्ति एक संग्रह से आती है तो आप आकार के लिए ऐसा कर सकते हैं।
ध्यान रखें कि Iterator अलग-अलग मूल्यों को ट्रेस करने के लिए सिर्फ एक इंटरफ़ेस है, आपके पास इस तरह के कोड बहुत अच्छे होंगे
new Iterator<Long>() {
final Random r = new Random();
@Override
public boolean hasNext() {
return true;
}
@Override
public Long next() {
return r.nextLong();
}
@Override
public void remove() {
throw new IllegalArgumentException("Not implemented");
}
};
या
new Iterator<BigInteger>() {
BigInteger next = BigInteger.ZERO;
@Override
public boolean hasNext() {
return true;
}
@Override
public BigInteger next() {
BigInteger current = next;
next = next.add(BigInteger.ONE);
return current;
}
@Override
public void remove() {
throw new IllegalArgumentException("Not implemented");
}
};
कोई और अधिक कुशल तरीका नहीं है, अगर आपके पास सब कुछ है। और अगर इटरेटर का उपयोग केवल एक बार किया जा सकता है, तो इटरेटर की सामग्री प्राप्त करने से पहले गिनती प्राप्त करना ... समस्याग्रस्त है।
समाधान या तो आपके आवेदन को बदलने के लिए है ताकि इसे गिनती की आवश्यकता न हो, या किसी अन्य माध्यम से गणना प्राप्त करने के लिए। (उदाहरण के लिए, पास करने के Collection
बजाय Iterator
...)
इटरेटर ऑब्जेक्ट में आपके संग्रह में शामिल तत्वों की समान संख्या होती है।
List<E> a =...;
Iterator<E> i = a.iterator();
int size = a.size();//Because iterators size is equal to list a's size.
लेकिन बजाय इटरेटर के आकार हो रही है और है कि आकार के सूचकांक 0 के माध्यम से पुनरावृत्ति की, यह पुनरावृति करने के लिए बेहतर विधि के माध्यम से है अगले () इटरेटर की।
a
, लेकिन केवल i
?