2016-08-15 13 views
6

(यह शायद https://stackoverflow.com/a/30312177/160137 से संबंधित है, लेकिन मुझे डर है कि मुझे अभी भी यह नहीं मिला है। इसलिए मैं इस सवाल से इस तरह से पूछ रहा हूं कि उम्मीद है कि इससे जवाब मिलेगा, मैं आसानी से समझ सकता हूं।)संग्राहक.तोलिस्ट() आदिम संग्रह पर क्यों काम नहीं करता है?

आम तौर पर जब मैं एक स्ट्रीम है मैं एक संग्रह कलेक्टरों कक्षा में स्थिर तरीकों में से एक का उपयोग करने के रूपांतरित कर सकते हैं: के रूप में,

List<String> strings = Stream.of("this", "is", "a", "list", "of", "strings") 
    .collect(Collectors.toList()); 

इसी तरह की प्रक्रिया आदिम धाराओं पर काम नहीं करता है, तथापि अन्य ने ध्यान दिया है:

IntStream.of(3, 1, 4, 1, 5, 9) 
    .collect(Collectors.toList()); // doesn't compile 

मैं इस के बजाय कर सकते हैं:

IntStream.of(3, 1, 4, 1, 5, 9) 
    .boxed() 
    .collect(Collectors.toList()); 

या मैं यह कर सकता:

IntStream.of(3, 1, 4, 1, 5, 9) 
    .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll); 

सवाल है, क्यों Collectors.toList() सिर्फ आदिम धाराओं के लिए ऐसा नहीं करता है? क्या यह है कि लपेटा प्रकार निर्दिष्ट करने का कोई तरीका नहीं है? यदि हां, तो यह क्यों काम नहीं करता है:

IntStream.of(3, 1, 4, 1, 5, 9) 
    .collect(Collectors.toCollection(ArrayList<Integer>::new)); // nope 

किसी भी अंतर्दृष्टि की सराहना की जाएगी।

+9

क्योंकि (जावा -8 में भी), कोई 'सूची ' नहीं है। आदिम प्रकार ** ** 'ऑब्जेक्ट' नहीं हैं। –

+3

हस्ताक्षर में जेनेरिक केवल प्राचीन प्रकार के साथ काम नहीं करेंगे। इस के रूप में सरल। – Dici

+4

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

उत्तर

3

खैर, यह IntStream हस्ताक्षर
<R,A> R collect(Collector<? super Integer,A,R> collector) एक अंतर्निहित मुक्केबाजी प्रदर्शन के साथ एक तरीका प्रदान करने देने के लिए कोई समस्या नहीं होगी। इसे return boxed().collect(collector); के रूप में सरल के रूप में कार्यान्वित किया जा सकता है।

प्रश्न यह है कि "इसे क्यों चाहिए" या दूसरी तरफ: आदिम स्ट्रीम विशेषज्ञता क्यों मौजूद है?

वे केवल बॉक्सिंग ओवरहेड के बिना स्ट्रीम ऑपरेशंस प्रदान करने के लिए प्रदर्शन कारणों से मौजूद हैं। तो यह एक स्पष्ट डिजाइन निर्णय है कि किसी भी ऑपरेशन को शामिल न करें जो जेनेरिक Stream इंटरफेस में पहले से मौजूद है क्योंकि इन सभी के लिए आप बस boxed().genericOperation(…) का आह्वान कर सकते हैं।

answer, you have linked संबंधित, लेकिन अलग-अलग विचारों को संबोधित करता है। यह collect विधि जेनेरिक Collector को स्वीकार नहीं करने वाला तरीका है, लेकिन Collector.ofInt जैसे एक आदिम विशेषज्ञता जो int बिना मुक्केबाजी के मूल्य एकत्र कर सकता है, लेकिन एक संग्राहक जो List<Integer> उत्पन्न करता है, अनिवार्य रूप से बॉक्स किए गए मान वाले होते हैं, इसका कोई लाभ नहीं होता है। प्रीबिल्ट कलेक्टरों में से केवल कुछ ही मुक्केबाजी से बच सकते हैं। वे सब के सब आदिम धाराओं (count(), sum(), min(), max(), summaryStatistics(), ...)

यह एक व्यापार बंद और वर्गों/इंटरफेस की संख्या संभावित प्रदर्शन लाभ के बीच है पर स्पष्ट टर्मिनल संचालन के रूप में प्रदान की जाती हैं। सामान्य रूप से धाराओं के मामले में, निर्णय IntStream, LongStream और DoubleStream बनाने का था, लेकिन कलेक्टरों के मामले में, निर्णय इस तरह की विशेषज्ञता को जोड़ना नहीं था।

1

आदिम प्रकारों के लिए List<> एक अतिरिक्त उप-उपयोग उपयोग है। इसलिए toArray पर्याप्त और पर्याप्त समझा गया था (= इष्टतम उपयोग)।

int[] array = IntStream.of(3, 1, 4, 1, 5, 9).toArray(); 
1
IntStream.of(3, 1, 4, 1, 5, 9) 
    .collect(Collectors.toList()); // doesn't compile 

धारा int है, सामान्य विधि toList() एक वस्तु मान लिया गया है। कोई मुकाबला नहीं।

IntStream.of(3, 1, 4, 1, 5, 9) 
    .boxed() 
    .collect(Collectors.toList()); 

धारा Integer है, सामान्य विधि toList() एक वस्तु मान लिया गया है। मिलान करें!

IntStream.of(3, 1, 4, 1, 5, 9) 
    .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll); 

धारा int है, और यह Integer के लिए सामान्य विधि toList() फिक्सिंग की तरह है। सिवाय इसके कि इंटस्ट्रीम में collect() विधि नहीं है जो संग्राहक स्वीकार करती है, केवल 3-पैरामीटर विधि।

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