जावा 8 में स्प्लिटर, कलेक्टर और स्ट्रीम को समझना


143

मुझे Streamजावा 8 में इंटरफेस को समझने में परेशानी हो रही है , खासकर जहां इसे Spliteratorऔर Collectorइंटरफेस के साथ करना है। मेरे समस्या यह है कि मैं बस नहीं समझ सकता है Spliteratorऔर Collectorअभी तक इंटरफेस है, और एक परिणाम के रूप में, Streamइंटरफ़ेस अभी भी कुछ हद तक मेरे लिए अस्पष्ट है।

वास्तव में ए Spliteratorऔर ए क्या है Collector, और मैं उनका उपयोग कैसे कर सकता हूं? अगर मैं अपनी खुद की Spliteratorया Collector(और शायद Streamउस प्रक्रिया में अपनी खुद की ) लिखने के लिए तैयार हूं, तो मुझे क्या करना चाहिए और क्या नहीं?

मैंने वेब के चारों ओर बिखरे हुए कुछ उदाहरणों को पढ़ा, लेकिन चूंकि यहां सब कुछ अभी भी नया है और परिवर्तनों के अधीन है, उदाहरण और ट्यूटोरियल अभी भी बहुत विरल हैं।

जवाबों:


142

आपको Spliteratorउपयोगकर्ता के रूप में लगभग निश्चित रूप से कभी नहीं निपटना चाहिए ; यह केवल आवश्यक अगर आपका लेखन होना चाहिए Collectionप्रकार अपने आप को और भी अनुकूलन के लिए इच्छुक उन पर संचालन parallelized।

इसके लायक क्या है, एक Spliteratorसंग्रह के तत्वों पर काम करने का एक तरीका है कि संग्रह के भाग को विभाजित करना आसान है, जैसे कि क्योंकि आप समानांतर कर रहे हैं और संग्रह के एक हिस्से पर काम करने के लिए एक धागा चाहते हैं, एक धागा दूसरे भाग पर काम करने के लिए, आदि।

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

int sum = widgets.stream()
                  .filter(w -> w.getColor() == RED)
                  .mapToInt(w -> w.getWeight())
                  .sum();

Collectorएक "कम" ऑपरेशन ला मैप / कम करने का सबसे सामान्यीकृत, सार संभव संस्करण है; विशेष रूप से, इसे समानांतरकरण और अंतिम चरणों का समर्थन करने की आवश्यकता है। एस के उदाहरणों में Collectorशामिल हैं:

  • संक्षेप, उदाहरण के लिए Collectors.reducing(0, (x, y) -> x + y)
  • StringBuilder आकर्षक, जैसे Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString)

31
Spliterator (रों) भी एक Iterable है कि एक संग्रह नहीं है स्ट्रीम करने के लिए एक तरीका प्रदान करता
बोहेमियन

2
मेरा मतलब था "एक कम ऑपरेशन, इस अर्थ में कि यह शब्द मानचित्र में कम है / कम है"
लुई वासरमैन

1
है Collectors.ofबीटा संस्करण है कि हटा दिया गया था या कर रहा हूँ-मैं कुछ कमी का एक पुराना तरीका? पूर्णता के लिए, के (x,y) -> x+yरूप में लिखा जा सकता है Integer::sum
जीन-फ्रांस्वा सवार्ड

3
एर, नो, सॉरी, इट्स कलेक्टर.ऑफ, नॉट कलेक्टर्स.ऑफ।
लुई वासरमैन

2
कलेक्टर का आपका उदाहरण अधिक उपयोगी होगा यदि आप बताएंगे कि आपके प्रत्येक कलेक्टर ने क्या किया है।
मिगेलमुनोज

90

Spliterator मूल रूप से "स्प्लिटेबल इटरेटर" का अर्थ है।

सिंगल थ्रेड पूरे स्प्लिटरेटर को खुद ही पार कर सकता है / प्रोसेस कर सकता है, लेकिन स्प्लिटेटर के पास एक ऐसा तरीका भी है, trySplit()जो किसी अन्य (आमतौर पर, दूसरे थ्रेड) के लिए एक सेक्शन को "स्प्लिट" करेगा जो प्रोसेस करने के लिए - कम स्प्लिटर को कम काम के साथ छोड़ देगा।

Collectorएक reduceफ़ंक्शन के विनिर्देश को जोड़ती है (मानचित्र-कम करने की प्रसिद्धि का), एक प्रारंभिक मूल्य के साथ, और दो परिणामों को संयोजित करने के लिए एक फ़ंक्शन (इस प्रकार संयुक्त रूप से काम की Spliterated धाराओं से परिणाम को सक्षम करने के लिए।)

उदाहरण के लिए, सबसे बुनियादी कलेक्टर में 0 का प्रारंभिक vaue होगा, एक मौजूदा परिणाम पर एक पूर्णांक जोड़ें, और उन्हें जोड़कर दो परिणामों को 'जोड़ देगा'। इस प्रकार पूर्णांक की एक अलग धारा है।

देख:


दो परिणामों को संयोजित करने के लिए एक मान?
जेसन लॉ

@JasonLaw - स्पष्ट! सलाह के लिये धन्यवाद।
थॉमस डब्ल्यू

5

सामान्य परिवर्तनशील कमी कार्य करने के लिए पूर्वनिर्धारित कलेक्टरों का उपयोग करने के उदाहरण निम्नलिखित हैं:

 // Accumulate names into a List
 List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());

 // Accumulate names into a TreeSet
 Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));

 // Convert elements to strings and concatenate them, separated by commas
 String joined = things.stream()
                       .map(Object::toString)
                       .collect(Collectors.joining(", "));

 // Compute sum of salaries of employee
 int total = employees.stream()
                      .collect(Collectors.summingInt(Employee::getSalary)));

 // Group employees by department
 Map<Department, List<Employee>> byDept
     = employees.stream()
                .collect(Collectors.groupingBy(Employee::getDepartment));

 // Compute sum of salaries by department
 Map<Department, Integer> totalByDept
     = employees.stream()
                .collect(Collectors.groupingBy(Employee::getDepartment,
                                               Collectors.summingInt(Employee::getSalary)));

 // Partition students into passing and failing
 Map<Boolean, List<Student>> passingFailing =
     students.stream()
             .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

2
यह ओप के प्रश्न का उत्तर नहीं देता है, साथ ही आपकी पोस्ट का कोई स्पष्टीकरण या विवरण नहीं है।
सिड

4

इंटरफ़ेस Spliterator- धाराओं की एक मुख्य विशेषता है ।

stream()और parallelStream()डिफ़ॉल्ट तरीकों में प्रस्तुत कर रहे Collectionइंटरफ़ेस। ये विधियाँ कॉल के माध्यम से Spliterator का उपयोग करती हैं spliterator():

...

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

default Stream<E> parallelStream() {
    return StreamSupport.stream(spliterator(), true);
}

...

Spliterator एक आंतरिक पुनरावृत्ति है जो धारा को छोटे भागों में तोड़ता है। इन छोटे भागों को समानांतर में संसाधित किया जा सकता है।

अन्य तरीकों में, Spliterator को समझने के लिए दो सबसे महत्वपूर्ण हैं:

  • boolean tryAdvance(Consumer<? super T> action) इसके विपरीत Iterator, यह अगले तत्व के साथ ऑपरेशन करने की कोशिश करता है। यदि ऑपरेशन सफलतापूर्वक निष्पादित हो जाता है, तो विधि वापस आ जाती है true। अन्यथा, रिटर्न false- इसका मतलब है कि धारा का तत्व या अंत का अभाव है।

  • Spliterator<T> trySplit() यह विधि डेटा के एक सेट को एक या दूसरे मानदंड (फ़ाइल का आकार, लाइनों की संख्या, आदि) के अनुसार कई छोटे सेटों में विभाजित करने की अनुमति देती है।


´अगर ऑपरेशन को सफलतापूर्वक अंजाम दिया गया है..´ आपको शायद इसे फिर से शुरू करना चाहिए। tryAdvance javadoc स्पष्ट है: aअगर एक शेष तत्व मौजूद है, तो उस पर दी गई कार्रवाई को पूरा करता है, सच लौटाता है; वरना झूठा मिलता है ।ica
पिरो का कहना है कि मोनिका से
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.