2016-03-16 7 views
22

जावा में, कोई आसानी से Stream.generate(supplier) के साथ एक अनंत स्ट्रीम उत्पन्न कर सकता है। हालांकि, मुझे एक धारा उत्पन्न करने की आवश्यकता होगी जो अंत में खत्म हो जाएगी।जावा में निर्मित उत्पन्न स्ट्रीम - एक कैसे बनाएं?

कल्पना कीजिए, उदाहरण के लिए, मैं निर्देशिका में सभी फ़ाइलों की एक स्ट्रीम चाहता हूं। फाइलों की संख्या बहुत बड़ी हो सकती है, इसलिए मैं सभी डेटा को पहले से नहीं इकट्ठा कर सकता हूं और उनमें से एक स्ट्रीम बना सकता हूं (collection.stream() के माध्यम से)। मुझे टुकड़े से अनुक्रम टुकड़ा उत्पन्न करने की जरूरत है। लेकिन धारा स्पष्ट रूप से कुछ बिंदु पर खत्म हो जाएगी, और टर्मिनल ऑपरेटरों (collect() या findAny()) पर काम करने की आवश्यकता है, इसलिए Stream.generate(supplier) यहां उपयुक्त नहीं है।

क्या जावा में ऐसा करने का कोई उचित आसान तरीका है, बिना पूरे स्ट्रीम इंटरफ़ेस को लागू किए?

मैं एक साधारण हैक के बारे में सोच सकता हूं - इसे अनंत के साथ कर रहा हूं, और जब सभी वास्तविक मूल्यों को लिया जाता है तो अपवाद या अपवाद फेंकना। लेकिन यह मानक स्ट्रीम ऑपरेटरों को तोड़ देगा, मैं इसे केवल अपने ऑपरेटरों के साथ उपयोग कर सकता हूं जो इस व्यवहार से अवगत हैं।

स्पष्टीकरण

टिप्पणी में लोगों ने मुझे takeWhile() ऑपरेटर का प्रस्ताव कर रहे हैं। यह मेरा मतलब नहीं था। प्रश्न को बेहतर तरीके से कैसे वाक्यांशित करें ... मैं नहीं पूछ रहा हूं कि किसी मौजूदा स्ट्रीम को फ़िल्टर (या सीमित) कैसे करें, मैं पूछ रहा हूं कि स्ट्रीम को कैसे उत्पन्न करें (गतिशील) - गतिशील रूप से, सभी तत्वों को पहले से लोड किए बिना, लेकिन स्ट्रीम के पास होगा एक सीमित आकार (अग्रिम में अज्ञात)।

समाधान

कोड मैं खोज रहा था

Iterator it = myCustomIteratorThatGeneratesTheSequence(); 
    StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false); 

मैं सिर्फ java.nio.file.Files, कैसे list(path) विधि कार्यान्वित किया जाता है में देखा है।

+0

मुझे नहीं लगता कि मैं समझता हूं। क्या आप यहां कुछ प्रकार के 'टेकवॉल्ड' की तलाश कर रहे हैं जैसे http://stackoverflow.com/q/20746429/1743880? – Tunaki

+1

क्या आपने [IntStream.range] (https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html#range-int-int-) जैसी विधियों पर एक नज़र डाली है। और मित्र? –

+0

'openjdk 9'' takeWhile() ' – Andrew

उत्तर

7

क्या जावा में ऐसा करने का कोई उचित आसान तरीका है, बिना पूरे स्ट्रीम इंटरफ़ेस को लागू किए?

एक साधारण .limit() गारंटी देता है कि यह समाप्त हो जाएगा। लेकिन यह हमेशा पर्याप्त शक्तिशाली नहीं है।

Stream कारखाने तरीकों स्ट्रीम प्रसंस्करण पाइपलाइन reimplementing बिना सीमा शुल्क धारा स्रोतों बनाने के लिए सबसे आसान दृष्टिकोण java.util.Spliterators.AbstractSpliterator<T> उपवर्गीकरण और java.util.stream.StreamSupport.stream(Supplier<? extends Spliterator<T>>, int, boolean)

को इसे पारित आप समानांतर धाराओं का उपयोग करने के लिए इच्छुक रहे हैं हो जाने के बाद ध्यान दें कि AbstractSpliterator केवल करने से इनकी पैदावार बंटवारे। यदि आपके स्रोत पर अधिक नियंत्रण है तो Spliterator इंटरफ़ेस को पूरी तरह कार्यान्वित करना बेहतर हो सकता है।

उदाहरण के लिए, निम्न स्निपेट एक स्ट्रीम बना देगा जो एक अनंत अनुक्रम 1,2,3 प्रदान करेगा ...

कि विशेष रूप से उदाहरण में आप IntStream.range()

इस्तेमाल कर सकते हैं लेकिन धारा स्पष्ट रूप से कुछ बिंदु पर खत्म हो जाएगा, और इस तरह टर्मिनल ऑपरेटर (इकट्ठा() या findAny()) इस पर काम करने की जरूरत है।

findAny() जैसे छोटे-सर्किटिंग संचालन वास्तव में, एक अनंत धारा पर समाप्त कर सकते हैं जब तक किसी भी तत्व से मेल खाता है वहाँ के रूप में।

संबंधित मुद्दे