क्या हम धाराओं को वापस करने के लिए एक सामान्य बात है जहाँ हम आम तौर पर संग्रह लौटाएंगे?


19

अपने एपीआई को विकसित करने के दौरान, जो किसी भी विरासत कोड से जुड़ा नहीं है, मैं अक्सर खुद को लिखने के तरीके ढूंढता हूं जो कि विशुद्ध रूप से स्ट्रीम पाइपलाइन हैं जो परिणाम एकत्र करके समाप्त हो जाते हैं। इस तरह:

ImmutableSet<T> deriveSomethingMeaningfulFromPrivateState() {
    return myPrivateThingies.stream()
        .map(this::ownerOfThing)
        .map(Owner::socialStatus)
        .filter(SocialStatus::isHeAFineMatey)
        .collect(MyCustomCollectors.toImmutableSet());
}

अब, इस वर्ग के अधिकांश ग्राहकों को आमतौर पर खोज करने के लिए संग्रह (इस मामले में, एक ImmutableSet) की आवश्यकता होगी और उस पर पुनरावृति हो सकती है, लेकिन कुछ क्लाइंट को स्ट्रीम होने से लाभ हो सकता है, इसलिए वे उस पर शीर्ष पर कुछ और कार्रवाई कर सकते हैं संग्रह से एक नई स्ट्रीम प्राप्त करने की आवश्यकता के बिना स्ट्रीम। इसलिए स्ट्रीम वापस करने से क्लिंस को उन विकल्पों का एक सुपरसेट मिलता है जो उनके पास होता अगर उनके पास सिर्फ कलेक्शन होता (आखिरकार, वे हमेशा collect()स्ट्रीम खुद कर सकते हैं:

Stream<T> deriveSomethingMeaningfulFromPrivateState() {
    return myPrivateThingies.stream()
        .map(this::ownerOfthing)
        .map(Owner::socialStatus)
        .filter(SocialStatus::isHeAFineMatey);
        // No collect
}

यह तरीका मेरे लिए लुभावना है क्योंकि मुझे इसमें कोई संभावित खामी नहीं दिखती। हालाँकि, मैंने इस दृष्टिकोण को कभी भी किसी भी पुस्तकालय में नहीं देखा है (शायद यह समझ में नहीं आया कि जावा 8 की उपस्थिति के बाद कई पुस्तकालय जारी किए गए थे), इसलिए मुझे इसे अपनाने में थोड़ा डर है। मौजूदा पुस्तकालय कक्षाएं आमतौर पर निजी राज्य से कुछ प्राप्त करने पर संग्रह लौटा देती हैं।

क्या कुछ बुरा है जो हो सकता है अगर मैं एक स्ट्रीम वापस करने का फैसला करता हूं जहां मेरा पूर्व-जावा -8 स्वयं एक संग्रह लौटाएगा? या शायद मैं एक एंटीपार्टन का कुछ कर रहा हूं जो निजी राज्य से प्राप्त होता है?

जवाबों:


14

यदि myPrivateThingiesआप परिवर्तनशील हैं, तो आपने अपने निजी राज्य और स्ट्रीम परिणामों के बीच एक छिपी निर्भरता बनाई है। यदि क्लाइंट के लिए अप्रत्यक्ष रूप myPrivateThingiesसे राज्य को बदलने का कारण है, तो collectमूल रूप से आपको देने के उद्देश्य से कॉल करने पर उसे एक अलग परिणाम प्राप्त होने वाला है।

यदि myPrivateThingiesअपरिवर्तनीय है, तो परिणाम संदर्भित रूप से पारदर्शी होगा, लेकिन एक और समस्या है जिसके लिए आपको बाहर देखना होगा: सिमेंटिक कचरा , यानी बड़ी मात्रा में स्मृति पर पकड़ जिसकी अब आवश्यकता नहीं है। मान लीजिए myPrivateThingiesकि बहुत बड़ा है और धारा एकत्र करने का परिणाम छोटा है। क्लाइंट उस ऑब्जेक्ट के सभी संदर्भों को फेंकने के बाद लंबे समय तक धारा पर पकड़ बना सकता है, जो इसे उत्पादित करता है, लेकिन streamयह अभी भी myPrivateThingiesकचरा एकत्र होने से बचा रहा है। उत्सुकता से परिणाम एकत्रित myPrivateThingiesकरने से मुक्ति मिल जाएगी।

यह वास्तव में जावा 7 से पहले हुआ था जब कॉलिंग substring। ओरेकल ने फैसला किया कि हर बार प्रतिस्थापन की नकल नहीं करने से संभावित दक्षता बचत, औसत उपयोगकर्ता को अत्यधिक मेमोरी खपत के साथ कभी-कभी आश्चर्यचकित करने के लायक नहीं है। यह कहना नहीं है कि पुराने व्यवहार (उदाहरण के लिए पार्सर्स) के लिए वास्तविक उपयोग के मामले नहीं थे, लेकिन अक्सर उत्सुकता से परिणाम एकत्र करना काफी तेजी से होता है, और जब ऐसा होता है तो आपके पास कोई पेशेवरों और संभावित चोर नहीं होते हैं।

दूसरी तरफ एक धारा को लौटाने से ग्राहक को यह चुनने की क्षमता मिलती है कि वे परिणाम प्राप्त करने के लिए किस डेटा संरचना का उपयोग करना चाहते हैं, जैसा कि आप उसके लिए एक चुनने का विरोध करते हैं। यह दोनों विकल्पों की पेशकश के लायक हो सकता है।


4

विचार करने के लिए सबसे महत्वपूर्ण बात: Streams को केवल एक बार पुनरावृत्त किया जा सकता है, जबकि आपके पास अधिक लचीलापन है Collection: आप परिणामों पर अतिरिक्त, दोहराव प्रसंस्करण करने के लिए और अधिक Streams या भी बनाना जारी रख सकते हैं Iterator

इसलिए यदि आप सुनिश्चित नहीं हैं कि विधि के कॉलर एक बार और केवल एक बार परिणामों का उपयोग करने जा रहे हैं, तो वापस लौटना बेहतर है Collection


आपके नमूना कोड में एक स्पष्ट त्रुटि है: SocialStatusकिसी व्यक्ति की अवधारणा क्यों होगी he?


3

मेरे विचार में, नहीं। धाराओं के साथ आप जिन चीजों को कर सकते हैं, वे उन चीजों का एक बहुत बड़ा सुपरसेट हैं जिन्हें आप संग्रह के साथ कर सकते हैं, और अक्सर उन्हें अधिक कुशल बनाया जा सकता है, इसलिए कोई कारण नहीं है कि वे अपरिचित को छोड़कर उपयोग न करें। "लैम्ब्डा एक्सप्रेशन जावा 8 की गेटवे ड्रग हैं, लेकिन स्ट्रीम्स ही असली लत हैं।" (वेंकट सुब्रमण्यम, जावा में कार्यात्मक प्रोग्रामिंग )

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.