मैंने प्रोजेक्ट लैंबडा मेलिंग सूचियों में से कई में एक जांच की और मुझे लगता है कि मुझे कुछ दिलचस्प चर्चाएँ मिलीं।
मुझे अब तक कोई संतोषजनक स्पष्टीकरण नहीं मिला है। यह सब पढ़ने के बाद मैंने निष्कर्ष निकाला कि यह सिर्फ एक चूक थी। लेकिन आप यहां देख सकते हैं कि एपीआई के डिजाइन के दौरान वर्षों में कई बार चर्चा की गई थी।
लैम्ब्डा लिब्स के स्पश्ट विशेषज्ञ
मुझे इस बारे में चर्चा मिली कि लैंबडा लिब्स के स्पेशलिस्ट मेलिंग लिस्ट में :
Iterable / Iterator.stream के तहत () सैम पुल्लारा ने कहा:
मैं ब्रायन के साथ काम कर रहा था, यह देखने के लिए कि किस तरह से लिमिट / सबस्ट्रीम फंक्शनलिटी [1] लागू की जा सकती है और उन्होंने सुझाव दिया कि इटरेटर में रूपांतरण इसके बारे में जाने का सही तरीका है। मैंने उस समाधान के बारे में सोचा था, लेकिन एक पुनरावृत्ति लेने और इसे एक धारा में बदलने का कोई स्पष्ट तरीका नहीं मिला। यह पता चला है कि यह वहां है, आपको बस इट्रेटर को एक विभाजक में बदलने की जरूरत है और फिर विभाजक को एक धारा में परिवर्तित करें। इसलिए यह मुझे इस बात पर फिर से विचार करने के लिए लाता है कि क्या हमें इन दोनों में से किसी एक को Iterable / Iterator से सीधे लटका देना चाहिए या दोनों।
मेरा सुझाव कम से कम इटरेटर पर है ताकि आप दोनों दुनियाओं के बीच सफाई से आगे बढ़ सकें और ऐसा करने के बजाय यह आसानी से खोजा जा सकेगा:
Streams.stream (Spliterators.spliteratorUnognSize (पुनरावृति, Spliterator.ORDERED)
और फिर ब्रायन गोएट्ज़ ने जवाब दिया :
मुझे लगता है कि सैम की बात यह थी कि पुस्तकालय की बहुत सारी कक्षाएं हैं जो आपको एक Iterator देती हैं, लेकिन जरूरी नहीं कि आप अपना स्वयं का स्प्लिटर भी लिखें। तो आप सभी कर सकते हैं कॉल स्ट्रीम (spliteratorUnognSize (पुनरावृत्त))। सैम सुझाव दे रहा है कि हम Iterator.stream को परिभाषित करें () आपके लिए।
मैं पुस्तकालय लेखकों / उन्नत उपयोगकर्ताओं के लिए स्ट्रीम () और स्प्लिटर () विधियों को रखना चाहूंगा।
और बादमें
"यह देखते हुए कि एक स्प्लिटर लिखने से एक Iterator लिखना आसान है, मैं एक Iterator के बजाय एक स्प्लिटेटर लिखना पसंद करूंगा (Iterator is so 90s :)"
आप इस बिंदु को याद कर रहे हैं, हालांकि। वहाँ बाहर वर्गों के लाखों रहे हैं कि पहले से ही आप एक Iterator हाथ। और उनमें से कई स्प्लिटर-रेडी नहीं हैं।
पिछले चर्चा में लैंबडा मेलिंग लिस्ट
यह वह उत्तर नहीं हो सकता है जिसकी आप तलाश कर रहे हैं, लेकिन प्रोजेक्ट लैंबडा मेलिंग सूची में इस पर संक्षिप्त चर्चा की गई थी। शायद यह इस विषय पर व्यापक चर्चा को बढ़ावा देने में मदद करता है।
Iterable से धाराओं के तहत ब्रायन Goetz के शब्दों में :
पीछे की और हटना...
स्ट्रीम बनाने के बहुत सारे तरीके हैं। आपके पास तत्वों का वर्णन करने के तरीके के बारे में अधिक जानकारी, अधिक कार्यक्षमता और प्रदर्शन लाइब्रेरी आपको दे सकती है। कम से कम अधिकांश जानकारी के लिए, वे हैं:
इटरेटर
इटरेटर + आकार
Spliterator
Spliterator जो इसके आकार को जानता है
Spliterator जो इसके आकार को जानता है, और आगे जानता है कि सभी उप-विभाजन उनके आकार को जानते हैं।
(कुछ लोगों को यह जानकर आश्चर्य हो सकता है कि हम उन मामलों में एक गूंगा पुनरावृत्ति से समानता भी निकाल सकते हैं, जहां क्यू (तत्व प्रति काम) अनैच्छिक है।)
यदि Iterable में एक स्ट्रीम () विधि होती है, तो यह केवल एक Iterator को Spliterator के साथ लपेटेगा, जिसमें कोई आकार की जानकारी नहीं होगी। लेकिन, ज्यादातर चीजें जो Iterable हैं उनमें आकार की जानकारी होती है। जिसका अर्थ है कि हम कमी धाराओं की सेवा कर रहे हैं। इतना अच्छा नहीं है।
स्टीफन द्वारा संग्रह के बजाय Iterable को स्वीकार करने की रूपरेखा के एक नकारात्मक पहलू यह है कि आप एक "छोटे पाइप" के माध्यम से चीजों को मजबूर कर रहे हैं और इसलिए जब यह उपयोगी हो सकता है तो आकार की जानकारी को छोड़ देना चाहिए। यह ठीक है यदि आप जो कुछ भी करने जा रहे हैं वह इसे छोड़ देना है, लेकिन यदि आप अधिक करना चाहते हैं, तो बेहतर है कि आप अपनी इच्छित सभी जानकारी को संरक्षित कर सकें।
Iterable द्वारा प्रदान किया गया डिफ़ॉल्ट वास्तव में एक भद्दा होगा - यह आकार को त्याग देगा भले ही Iterables के विशाल बहुमत को उस जानकारी का पता हो।
अंतर्विरोध?
हालांकि, ऐसा लगता है कि चर्चा उन परिवर्तनों पर आधारित है जो विशेषज्ञ समूह ने धाराओं के प्रारंभिक डिजाइन के लिए की थी जो शुरू में पुनरावृत्तियों पर आधारित थी।
फिर भी, यह ध्यान रखना दिलचस्प है कि संग्रह जैसे इंटरफ़ेस में, स्ट्रीम विधि को इस प्रकार परिभाषित किया गया है:
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
जो Iterable इंटरफ़ेस में उपयोग किए जा रहे सटीक समान कोड हो सकता है।
इसलिए, इस कारण मैंने कहा कि यह उत्तर शायद संतोषजनक नहीं है, लेकिन फिर भी चर्चा के लिए दिलचस्प है।
रिफैक्टरिंग के साक्ष्य
मेलिंग सूची में विश्लेषण के साथ जारी है, ऐसा लगता है कि स्प्लिटइंटरेटर विधि मूल रूप से संग्रह इंटरफ़ेस में थी, और 2013 में कुछ बिंदु पर वे इसे Iterable तक ले गए।
स्प्लिटइंटरेटर को कलेक्शन से इटरटेबल तक खींचो ।
निष्कर्ष / सिद्धांतों?
तब संभावना है कि Iterable में विधि की कमी सिर्फ एक चूक है, क्योंकि ऐसा लगता है कि उन्हें स्ट्रीम विधि को स्थानांतरित करने के साथ-साथ विभाजन से Iterable तक विभाजन को स्थानांतरित करना चाहिए।
यदि अन्य कारण हैं जो स्पष्ट नहीं हैं। किसी और के पास अन्य सिद्धांत हैं?