दिलचस्प पोस्ट
वेब एपलीकेशन से एएसपी.नेट में सत्र का पता कैसे खोज सकता है? jqGrid Reposition पुष्टिकरण बॉक्स को हटा दें एक हैश की चाबी कैसे पाएं? Sys.stdout.flush () विधि का उपयोग सी # में प्रोग्राम प्रवाह को ट्रेस करने के लिए मौजूदा संभावनाएं? उपयोग के लिए मूल्यबीन वर्ग विशेषता … अमान्य है RecyclerView अंदर ScrollView लचीला Recycler आइटम ऊंचाई के साथ का उपयोग करें जावा में विरल मैट्रिस / एरेज़ महत्वपूर्ण स्तर के साथ बॉक्स प्लॉट कैसे आकर्षित करें? अंतिम संशोधित फ़ाइल को एक निर्देशिका में प्राप्त करें एक खिड़की पर कीस्ट्रोक्स भेजने के लिए कैसे? क्या मैं सी ++ में किसी अन्य कन्स्ट्रक्टर (कन्स्ट्रक्टर चेनिंग) से कन्स्ट्रक्टर को बुला सकता हूं? DLL में एक क्लास का उपयोग कैसे करें? जेएस / सीएसएस से सिस्टम डीपीआई / पीपीआई का पता लगा रहा है? PHP के साथ दो छवियों को मर्ज करना

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

मैं जो कार्यशील प्रोग्रामिंग की नई 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 

Solutions Collecting From Web of "लैम्ब्डा लौटने वाले जावा लैम्ब्डा"

आप जावा 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());