दिलचस्प पोस्ट
Parameters.Add और Parameters.AddWithValue के बीच अंतर NSDictionary में सभी NSNull ऑब्जेक्ट को बदलें MySQL: किसी भी रेंज में सभी तिथियां चुनें, भले ही कोई रिकॉर्ड मौजूद न हो रिक्रिकेस का प्रयोग करके पुनरावर्ती चेकइन ASP.Net MVC Html.HiddenFor गलत मान के साथ एंड्रॉइड स्टूडियो – कोई जेवीएमएम स्थापना नहीं मिली एक बयान में कई पोस्ट और पूर्व वेतन वृद्धि का उत्पादन JQuery के मूल (), माता-पिता () और निकटतम () फ़ंक्शंस के बीच अंतर उद्देश्य-सी में गुण और एक्सेसर्स मैं SQL सर्वर प्रबंधन स्टूडियो के साथ एक समग्र कुंजी कैसे बनाऊं? सबप्रोसेस Popen और कॉल (मैं उन्हें कैसे उपयोग कर सकते हैं) के बीच अंतर क्या है? पहली पंक्ति के बाद लाइन लूप बंद होने पर शैल स्क्रिप्ट बंद हो जाती है मैं फिल्म के रूप में UIImage सरणी कैसे निर्यात करूं? सीएसएस क्षैतिज स्क्रॉल कैसे एक बेस64 स्ट्रिंग में एक छवि को परिवर्तित करने के लिए?

लैम्ब्डा लौटने वाले जावा लैम्ब्डा

मैं जो कार्यशील प्रोग्रामिंग की नई jdk8 भूमि में एक अपेक्षाकृत मूल बात है, लेकिन ऐसा करने की कोशिश कर रहा हूं, लेकिन यह काम नहीं कर सकता। मेरे पास यह कार्य कोड है:

import java.util.*; import java.util.concurrent.*; import java.util.stream.*; public class so1 { public static void main() { List<Number> l = new ArrayList<>(Arrays.asList(1, 2, 3)); List<Callable<Object>> checks = l.stream(). map(n -> (Callable<Object>) () -> { System.out.println(n); return null; }). collect(Collectors.toList()); } } 

यह संख्याओं की एक सूची लेता है और उन कार्यों की एक सूची तैयार करता है जो उन्हें प्रिंट कर सकते हैं। हालांकि कॉल करने के लिए स्पष्ट कलाकार बेमानी लगता है। यह मुझे और IntelliJ करने के लिए लगता है और हम दोनों सहमत हैं कि यह भी काम करना चाहिए:

 List<Callable<Object>> checks = l.stream(). map(n -> () -> { System.out.println(n); return null; }). collect(Collectors.toList()); 

हालांकि मुझे एक त्रुटि मिलती है:

 so1.java:10: error: incompatible types: cannot infer type-variable(s) R List<Callable<Object>> checks = l.stream().map(n -> () -> {System.out.println(n); return null;}).collect(Collectors.toList()); ^ (argument mismatch; bad return type in lambda expression Object is not a functional interface) where R,T are type-variables: R extends Object declared in method <R>map(Function<? super T,? extends R>) T extends Object declared in interface Stream 1 error 

वेब के समाधान से एकत्रित समाधान "लैम्ब्डा लौटने वाले जावा लैम्ब्डा"

आप जावा 8 की लक्ष्य टाइपिंग की एक सीमा को दबाते हैं, जो किसी विधि आमंत्रण के रिसीवर पर लागू होता है। पैरामीटर प्रकारों के लिए टाईपिंग टाईपिंग (ज्यादातर समय) करते समय यह ऑब्जेक्ट या अभिव्यक्ति के लिए काम नहीं करता है, जिस पर आप विधि का आह्वान करते हैं।

यहां, l.stream(). map(n -> () -> { System.out.println(n); return null; }) l.stream(). map(n -> () -> { System.out.println(n); return null; }) collect(Collectors.toList()) की रिसीवर है collect(Collectors.toList()) विधि का आह्वान, ताकि लक्ष्य प्रकार की List<Callable<Object>> लिए नहीं माना जाता है

यह साबित करना आसान है कि नेस्टेड लैम्ब्डा भाव काम करते हैं यदि लक्ष्य प्रकार पता है, उदा

 static <T> Function<T,Callable<Object>> toCallable() { return n -> () -> { System.out.println(n); return null; }; } 

समस्याओं के बिना काम करता है और आप इसे अपनी मूल समस्या को हल करने के लिए उपयोग कर सकते हैं

 List<Callable<Object>> checks = l.stream() .map(toCallable()).collect(Collectors.toList()); 

आप एक सहायक विधि को शुरू करने से समस्या का समाधान भी कर सकते हैं जो विधि प्राप्तकर्ता से पैरामीटर पर पहली अभिव्यक्ति की भूमिका को बदलता है

 // turns the Stream s from receiver to a parameter static <T, R, A> R collect(Stream<T> s, Collector<? super T, A, R> collector) { return s.collect(collector); } 

और मूल अभिव्यक्ति को फिर से लिखना

 List<Callable<Object>> checks = collect(l.stream().map( n -> () -> { System.out.println(n); return null; }), Collectors.toList()); 

यह कोड की जटिलता को कम नहीं करता है लेकिन बिना किसी समस्या के संकलित किया जा सकता है। मेरे लिए, यह एक डेजा वीयू है जब जावा 5 और जेनरिक बाहर आए, तो प्रोग्रामर को new भावों पर टाइप पैरामीटर दोहराने पड़ते थे, जबकि सामान्य रूप से अभिव्यक्ति को एक सामान्य पद्धति में लपेटते हुए साबित हुआ कि प्रकार की कोई समस्या नहीं है। प्रोग्रामर को इस तरह के तर्कों ("डायमंड ऑपरेटर" का उपयोग करके) के इन अनावश्यक पुनरावृत्तियों को छोड़ने की अनुमति देने से पहले यह जावा 7 तक ले गया था। अब हमारे पास इसी तरह की स्थिति है, एक अन्य विधि में एक अभिविन्यास अभिव्यक्ति लपेटकर, रिसीवर को एक पैरामीटर में बदल कर, यह साबित करता है कि यह सीमा अनावश्यक है इसलिए हम जावा 10 में इस सीमा से छुटकारा पा सकते हैं …

मैंने अभी तक सटीक नियमों में उलझा नहीं किया है कि किस प्रकार अनुमान के साथ काम करता है lambdas सामान्य भाषा के डिज़ाइन के दृष्टिकोण से, हालांकि, भाषा के नियमों को लिखना हमेशा संभव नहीं होता है, जो कि कंपाइलर को जो कुछ भी हम सोचते हैं उसे समझने की अनुमति दें। मैं एडीए-भाषा कंपाइलर के लिए एक कंपाइलर रखरखाता रहा हूं और मैं कई भाषा डिजाइन मुद्दों से परिचित हूं। एडा बहुत सारे मामलों में टाइप इंफॉर्मेशन का उपयोग करता है (जहां एक कंस्ट्रक्शन का प्रकार निर्माण के साथ पूरे अभिव्यक्ति को देखे बिना निर्धारित नहीं किया जा सकता है, जो मुझे लगता है कि यह जावा लैम्ब्डा एक्सप्रेशन के साथ मामला भी है)। कुछ भाषा नियम हैं जो कम्पाइलर को कुछ अभिव्यक्तियों को अस्पष्ट रूप से अस्वीकार करने का कारण बनते हैं, जब सिद्धांत में, वास्तव में केवल एक संभव व्याख्या है। एक कारण, अगर मुझे सही ढंग से याद आती है, तो किसी व्यक्ति को एक ऐसा मामला मिल गया है जहां एक नियम ने संकलक को सही व्याख्या का पता लगाया होता, तो कम्पाइलर ने 17 पासेस को एक अभिव्यक्ति के माध्यम से सही ढंग से व्याख्या करने के लिए बनाने की आवश्यकता होती।

इसलिए जब हम सोच सकते हैं कि एक संकलक को "किसी विशेष मामले में कुछ समझने में सक्षम होना चाहिए", यह सिर्फ सादा ही असंभव हो सकता है

मैं इस एक ही मुद्दे पर गया और इसे सामान्य रूप से निर्दिष्ट करने के लिए जेनेरिक प्रकार-पैरामीटर निर्दिष्ट करने से इसे हल करने में सक्षम था:

 List<Callable<Object>> checks = l.stream(). <Callable<Object>>map(n -> () -> { System.out.println(n); return null; }). collect(Collectors.toList());