java - जावा 8 स्ट्रीम की.min() और.max(): यह संकलन क्यों करता है?




java-8 java-stream (4)

नोट: यह प्रश्न एक मृत लिंक से निकला है जो पिछले SO प्रश्न था, लेकिन यहां जाता है ...

यह कोड देखें ( नोट: मुझे पता है कि यह कोड "काम नहीं करेगा" और Integer::compare का उपयोग किया जाना चाहिए - मैंने इसे लिंक किए गए प्रश्न से निकाला है ):

final ArrayList <Integer> list 
    = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList());

System.out.println(list.stream().max(Integer::max).get());
System.out.println(list.stream().min(Integer::min).get());

.min() और .min() के .min() अनुसार, दोनों का तर्क एक Comparator होना चाहिए। फिर भी यहां विधि संदर्भ Integer वर्ग के स्थिर तरीकों के लिए हैं।

तो, यह बिल्कुल संकलित क्यों करता है?


डेविड एम। लॉयड द्वारा दी गई जानकारी के अलावा कोई भी यह जोड़ सकता है कि जिस तंत्र को इसे अनुमति देने की अनुमति दी जाती है उसे लक्ष्य टाइपिंग कहा जाता है।

विचार यह है कि कंपाइलर लैम्ब्डा अभिव्यक्तियों या विधि संदर्भों को निर्दिष्ट करता है, केवल अभिव्यक्ति पर ही निर्भर नहीं होता है, बल्कि यह कहां उपयोग किया जाता है।

अभिव्यक्ति का लक्ष्य वह चर है जिसके परिणामस्वरूप उसका परिणाम असाइन किया गया है या पैरामीटर जिसके परिणामस्वरूप पारित किया गया है।

लैम्ब्डा अभिव्यक्तियों और विधि संदर्भों को एक प्रकार असाइन किया जाता है जो उनके लक्ष्य के प्रकार से मेल खाता है, यदि ऐसा कोई प्रकार पाया जा सकता है।

अधिक जानकारी के लिए जावा ट्यूटोरियल में टाइप इनफरेंस सेक्शन देखें।


मुझे अधिकतम और मिनट प्राप्त करने वाले सरणी के साथ एक त्रुटि हुई, इसलिए मेरा समाधान था:

int max = Arrays.stream(arrayWithInts).max().getAsInt();
int min = Arrays.stream(arrayWithInts).min().getAsInt();

यह काम करता है क्योंकि Integer::min Comparator<Integer> इंटरफ़ेस के कार्यान्वयन के लिए हल करता है।

IntBinaryOperator Integer::min का विधि संदर्भ IntBinaryOperator Integer.min(int a, int b) को हल IntBinaryOperator , IntBinaryOperator को हल किया IntBinaryOperator , और संभावित रूप से IntBinaryOperator कहीं भी इसे IntBinaryOperator BinaryOperator<Integer> बनाता है।

और Stream<Integer> के min() resp max() विधियों को लागू करने के लिए Comparator<Integer> इंटरफ़ेस से पूछें।
अब यह एक विधि को हल करता है Integer compareTo(Integer o1, Integer o2)BinaryOperator<Integer> का प्रकार कौन सा है।

और इस प्रकार जादू हुआ है क्योंकि दोनों विधियां BinaryOperator<Integer>


Comparator एक कार्यात्मक इंटरफ़ेस है , और Integer::max उस इंटरफ़ेस का अनुपालन करता है (ऑटोबॉक्सिंग / अनबॉक्सिंग के बाद विचार किया जाता है)। इसमें दो int मान होते हैं और एक int - जैसे आप एक Comparator<Integer> से (फिर से, पूर्णांक / int अंतर को अनदेखा करने के लिए squinting) की अपेक्षा करेंगे।

हालांकि, मैं यह सही काम करने की उम्मीद नहीं करता, यह देखते हुए कि Integer.max Comparator.compare के अर्थशास्त्र का पालन नहीं करता है। और वास्तव में यह वास्तव में सामान्य रूप से काम नहीं करता है। उदाहरण के लिए, एक छोटा बदलाव करें:

for (int i = 1; i <= 20; i++)
    list.add(-i);

... और अब max मान -20 है और min मान -1 है।

इसके बजाए, दोनों कॉलों को Integer::compare करना चाहिए:

System.out.println(list.stream().max(Integer::compare).get());
System.out.println(list.stream().min(Integer::compare).get());




java-stream