2015-04-17 12 views
26

में समानांतर धारा क्यों एकत्रित की जाती है क्यों forEach यादृच्छिक क्रम में प्रिंट संख्याएं, जबकि collect समानांतर धारा से भी मूल क्रम में तत्व एकत्र करता है?जावा 8

Integer[] intArray = {1, 2, 3, 4, 5, 6, 7, 8}; 
List<Integer> listOfIntegers = new ArrayList<>(Arrays.asList(intArray)); 

System.out.println("Parallel Stream: "); 
listOfIntegers 
    .stream() 
    .parallel() 
    .forEach(e -> System.out.print(e + " ")); 
System.out.println(); 

// Collectors   
List<Integer> l = listOfIntegers 
    .stream() 
    .parallel() 
    .collect(Collectors.toList()); 
System.out.println(l); 

आउटपुट:

Parallel Stream: 
8 1 6 2 7 4 5 3 
[1, 2, 3, 4, 5, 6, 7, 8] 

उत्तर

32

यहां दो अलग-अलग प्रकार के "ऑर्डरिंग" चल रहे हैं, जो चर्चा को भ्रमित कर देता है।

एक प्रकार मुठभेड़ आदेश है, जिसे streams documentation में परिभाषित किया गया है। इस बारे में सोचने का एक अच्छा तरीका स्थानिक या स्रोत संग्रह में तत्वों के क्रम में बाएं से दाएं आदेश है। यदि स्रोत List है, तो पहले के तत्वों को बाद के तत्वों के बाईं ओर देखें।

वहाँ भी प्रसंस्करण या अस्थायी आदेश है, जो दस्तावेज में परिभाषित नहीं है, लेकिन जो समय जिस क्रम में तत्वों अलग धागे द्वारा संसाधित कर रहे है। यदि किसी सूची के तत्वों को अलग-अलग धागे द्वारा समानांतर में संसाधित किया जा रहा है, तो थ्रेड बाएं तत्व से पहले सूची में सबसे सही तत्व को संसाधित कर सकता है। लेकिन अगली बार यह नहीं हो सकता है।

यहां तक ​​कि जब संगणना समानांतर में किया जाता है, सबसे Collectors और कुछ टर्मिनल संचालन ध्यान से व्यवस्थित कर रहे हैं, ताकि वे अस्थायी आदेश जिसमें विभिन्न धागे की प्रक्रिया हो सकती है गंतव्य के लिए के माध्यम से स्रोत से मुठभेड़ आदेश की रक्षा, स्वतंत्र रूप से प्रत्येक तत्व।

ध्यान दें कि forEach टर्मिनल ऑपरेशन मुठभेड़ आदेश को संरक्षित करता है। इसके बजाए, यह अगले परिणाम का उत्पादन करने के लिए जो भी धागा होता है, उसके द्वारा चलाया जाता है। यदि आप forEach जैसे कुछ चाहते हैं जो मुठभेड़ आदेश को सुरक्षित रखता है, तो इसके बजाय forEachOrdered का उपयोग करें।

मुद्दों का ऑर्डर करने के बारे में और चर्चा के लिए Lambda FAQ भी देखें।

+0

धन्यवाद! उत्कृष्ट स्पष्टीकरण। –

9

Collectors.toList method निर्दिष्ट करता है कि लौटे Collector मुठभेड़ क्रम में सूची में तत्वों कहते हैं।

रिटर्न:

एक कलेक्टर जो एक सूची में सभी इनपुट तत्वों एकत्र करता है, मुठभेड़ के क्रम में

इससे कोई फर्क नहीं पड़ता कि Stream समानांतर है; आदेश संरक्षित है।

साथ ही, Collectors स्रोत कोड देख, Collector कॉल addAll एक ArrayList मर्ज पर लौट आए, और उस क्रम को बरकरार रखता है। जैसे अगर एक थ्रेड में {1, 2} है और अगले थ्रेड में {3, 4} है, तो addAll पर कॉल {1, 2, 3, 4} उत्पन्न करता है। इसके अलावा, लौटा Collector में UNORDERED विशेषता नहीं है।

+0

'समांतर' के बाद आदेश कैसे ज्ञात किया जा सकता है? –

+2

आपको क्या लगता है कि 'समानांतर' आदेश को त्याग देगा? –

+0

टर्मिनल ऑपरेशन पहुंचने के बाद यह आदेश को त्याग देगा। जरूरी नहीं, सीपीयू और ओएस पर निर्भर करता है, लेकिन पहला उदाहरण 'के लिए' साबित करता है। –