2016-07-11 18 views
7

मैं जावा 8 के साथ शुद्ध फ़ंक्शन लिखना चाहता था जो एक संग्रह के रूप में संग्रह लेता है, उस संग्रह के प्रत्येक ऑब्जेक्ट में कुछ परिवर्तन लागू करता है और अद्यतन के बाद एक नया संग्रह देता है। मैं एफपी सिद्धांतों का पालन करना चाहता हूं इसलिए मैं एक तर्क के रूप में पारित संग्रह को अद्यतन/संशोधित नहीं करना चाहता हूं।जावा 8 स्ट्रीम तत्वों को संशोधित करें

क्या स्ट्रीम एपीआई के साथ पहले मूल संग्रह की एक प्रति बनाये बिना और फिर लूप के लिए प्रत्येक या 'सामान्य' के लिए उपयोग किए बिना ऐसा करने का कोई तरीका है? नीचे

नमूना वस्तु और मान की सुविधा देता है कि मैं वस्तु संपत्ति से एक के लिए एक पाठ संलग्न करना चाहते हैं:

public class SampleDTO { 
    private String text; 
} 

तो मैं नीचे के समान कुछ करना चाहता हूँ, लेकिन संग्रह को संशोधित किए बिना। मान लीजिए "सूची" एक List<SampleDTO> है।

list.forEach(s -> { 
    s.setText(s.getText()+"xxx"); 
}); 
+1

मैं कहूंगा कि यह यहां कार्यात्मक प्रोग्रामिंग के सिद्धांत के खिलाफ थोड़ा सा है। विचार राज्य को विचलित नहीं करना है, लेकिन फ़ंक्शन के उत्पाद के रूप में नया राज्य बनाएं। यही कारण है कि, मूल सूची को म्यूट करने के बजाय, आपको एक नई सूची बनाने के लिए जावा स्ट्रीम एपीआई द्वारा प्रदान किए गए 'मानचित्र' फ़ंक्शन का उपयोग करना चाहिए। – christopher

उत्तर

12

आप कुछ विधि/निर्माता कि इस तरह के एक प्रतिलिपि निर्माता के रूप में एक मौजूदा SampleDTO उदाहरण, की एक प्रति उत्पन्न होना आवश्यक है।

तो फिर तुम map कर सकते हैं प्रत्येक मूल SampleDTO उदाहरण एक नया SampleDTO उदाहरण के लिए, और उन्हें collect एक नया List में:

List<SampleDTO> output = 
    list.stream() 
     .map(s-> { 
        SampleDTO n = new SampleDTO(s); // create new instance 
        n.setText(n.getText()+"xxx"); // mutate its state 
        return n; // return mutated instance 
       }) 
     .collect(Collectors.toList()); 
2

इस और अधिक सुरुचिपूर्ण तरह से मैं कक्षा में साथ एक Method बनाने का सुझाव देते हैं बनाने के लिए।

public class SampleDTO { 
private String text; 
public String getText() { 
    return text; 
} 

public void setText(String text) { 
    this.text = text; 
} 

public SampleDTO(String text) { 
    this.text = text; 
} 

public SampleDTO getSampleDTO() { 
    this.setText(getText()+"xxx"); 
    return this; 
} 
    } 

और इसे पसंद जोड़ें:

List<SampleDTO> output =list.stream().map(SampleDTO::getSampleDTO).collect(Collectors.toList(); 
+0

@FedericoPeraltaSchaffner टिप्पणी और डाउनवोट के लिए धन्यवाद। मैंने इसे ठीक कर दिया है। अब यह – soorapadman

+0

संकलित करेगा I downvoted क्योंकि आपके उत्तर में 1 वोट था और मैं अन्य उत्तरों को बढ़ावा देना चाहता था जो सही थे, क्षमा करें अगर वह बहुत कठोर था।अब जब आपने इसे सही किया है, मैंने न केवल मेरे डाउनवोट को वापस कर दिया है बल्कि ऊपर उठाया है। –

+0

हालांकि, अब मूल वस्तु संशोधित की गई है, और ओपी न तो मूल सूची और न ही इसके तत्वों को बदलना चाहता था। आपको मूल ऑब्जेक्ट की एक प्रति अपनी टेक्स्ट विशेषता संशोधित करने पर विचार करना चाहिए। –

1

स्ट्रीम ताकि आप चारों ओर एक नई धारा/सूची/सरणी

कहा जा रहा है कि आप उपयोग कर सकते हैं बनाने के लिए की आवश्यकता होगी, नहीं मिल सकता है तार की तरह अडिग हैं। एक नया संग्रह पोस्ट परिवर्तन वापस करने के लिए एकत्र करें (

List<Integer> result = inList.stream().map().Collect() 
1

मुझे लगता है कि यह बेहतर होगा, खासकर यदि बहु-थ्रेडेड काम कर रहे हैं, तो मूल सूची को एक नई संशोधित सूची में स्ट्रीम करने के लिए या जो कुछ भी वांछित है।

नई सूची या मानचित्र या जो भी अन्य संरचना आप चाहते हैं स्ट्रीमिंग प्रक्रिया के हिस्से के रूप में बनाई जा सकती है।

जब स्ट्रीमिंग प्रक्रिया पूरी हो जाती है, तो बस मूल को नए से स्वैप करें।

यह सब एक सिंक्रनाइज़ ब्लॉक में होना चाहिए।

इस तरह, आपको कम करने के लिए अधिकतम प्रदर्शन और समांतरता मिलती है या जो कुछ भी आप कर रहे हैं, और परमाणु स्वैप के साथ खत्म हो जाते हैं।

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