2015-03-06 13 views
5

के साथ जेनेरिक रिटर्न टाइप को कवर करना मैं जावा 8 में कुछ उच्च-ऑर्डर-फ़ंक्शंस में लैम्ब्डा अभिव्यक्ति के रिटर्न प्रकार से जेनेरिक प्रकार की जानकारी को संरक्षित करने की कोशिश कर रहा हूं। मैंने इस वास्तविक परीक्षण को मेरे परीक्षण को सरल बना दिया है मामला। समस्या यह नहीं है कि मैं कोड को बिल्कुल ठीक करने की अपेक्षा करता हूं, लेकिन मुझे अपेक्षाकृत सामान्य प्रकार (0) Rjava.lang.String के रूप में अनुमानित करने की अपेक्षा करता है और फ़ंक्शन कॉल के माध्यम से किया जाता है।जावा 8 - लैम्बडास

import java.util.function.Function; 

public class AdamTest { 

    public final static void main(final String args[]) { 
     final AdamTest adamTest = new AdamTest(); 

     final String s = adamTest.thing2(7).apply(i -> i.toString()); 
     System.out.println(s); 
    } 


    private <R> R fn1(final Function<Integer, R> op) { 
     return op.apply(10); 
    } 

    private <R> Function<Function<Integer, R>, R> thing2(final Integer val) { 
     return fn1(i -> new Function<Function<Integer, R>, R>() { 
       @Override 
       public R apply(Function<Integer, R> op) { 
        return op.apply(val * i); 
       } 
      } 
     ); 
    } 
} 

फिलहाल यह कोड final String s = adamTest.thing2(7).apply(i -> i.toString()); इस लाइन के कारण संकलित नहीं होता है। मुझे लगता है कि मेरे पास मेरे प्रकार की सीमाओं के साथ कुछ गड़बड़ है, क्योंकि संकलक thing2(7).apply के रिटर्न प्रकार का अनुमान लगाने में सक्षम नहीं लगता है और String की बजाय Object की रिपोर्ट करता है, जिसे मैं उम्मीद कर रहा था।

मैं कैसे सामान्य प्रकार सीमा सही मिलता है ताकि सही वापसी प्रकार अर्थात java.lang.Stringमान लिया जाता है संकलक द्वारा?

+0

क्या आप जो त्रुटि प्राप्त कर रहे हैं उसे जोड़ सकते हैं? –

+1

संकलक बाएं से दाएं अभिव्यक्ति का मूल्यांकन करता है; समस्या 'adamTest.thing2 (7)' पर होती है। कंपाइलर प्रकार को समझने के लिए '.apply' को नहीं देखता है, और इसके बिना यह संभव नहीं है। –

+0

आप वास्तव में क्या करने की कोशिश कर रहे हैं? यह पूरी तरह से अस्पष्ट है। – fge

उत्तर

5

जैसा कि पहले ही कहा, बाएं से दाएं उन बयानों मूल्यांकन किया जाता है।

सही प्रकार का उपयोग करने के संकलक बाध्य करने के लिए, तो आप बस के रूप में

final String s = adamTest.<String>thing2(7).apply(String::valueOf); 

संपादित करें यह लिख सकते हैं: टिप्पणियों के अनुसार, लैम्ब्डा अभिव्यक्ति के लिए एक विधि संदर्भ (क्लीनर दिखता है) द्वारा प्रतिस्थापित किया जा सकता।

+0

इसके अलावा, आप विधि संदर्भ के साथ i.toString() पर विधि कॉल को प्रतिस्थापित कर सकते हैं। – buftlica

+0

@MatkoMedenjak दुर्भाग्यवश ऐसा नहीं किया जा सकता है। वर्ग 'इंटीगर'' टूस्ट्रिंग 'नामक दो विधियों को परिभाषित करता है: एक स्थिर विधि ['Integer.toString (int)'] (http://docs.oracle.com/javase/8/docs/api/java/lang/ Integer.html # toString-int-) और एक गैर स्थैतिक विधि ['Integer.toString()'] (http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html #तार--)। विधि संदर्भ 'इंटीजर :: टूस्ट्रिंग' का उपयोग करते हुए संकलक उनके बीच अंतर नहीं कर सकता है। – Seelenvirtuose

+0

धन्यवाद @ सेलेनवर्टुओस यह वह समाधान है जो मैं स्वयं आया था, लेकिन किसी भी तरह से मुझे वास्तव में संकलक से बेहतर संदर्भ की उम्मीद थी और इसलिए मुझे लगा कि मैंने अपने जेनेरिक में गलती की है, इसलिए मैंने सवाल पूछा। – adamretter

5

मुझे नहीं लगता कि इसे बिना किसी बगैर तय किया जा सकता है (शायद कोई बेहतर जानता है)। एक वैकल्पिक दो पंक्तियों में अपने बयान विभाजित करने के लिए है:

Function<Function<Integer, String>, String> thing2 = adamTest.thing2(7); 
final String s = thing2.apply(i -> i.toString()); 

भी ध्यान रखें कि thing2 सरल किया जा सकता:

private <R> Function<Function<Integer, R>, R> thing2(final Integer val) { 
    return fn1(i -> (op -> op.apply(val * i))); 
} 
+0

के उत्तर में सुझाया गया था, यदि जावा में 'ऑटो' प्रकार था, तो मैं इसे दो कथनों में विभाजित कर दूंगा, लेकिन जैसा कि मैं @ सेलेनवर्टूज़ द्वारा सुझाए गए जेनेरिक कलाकार का उपयोग करना पसंद नहीं करता हूं। हालांकि, सरलीकरण की तरह मुझे धन्यवाद। – adamretter

-2

आपको लैम्ब्डा अभिव्यक्ति को सक्षम करने के लिए अपने कंपाइलर की सेटिंग्स पर जाना होगा। इंटेलिज के साथ एक उदाहरण यहां दिया गया है। यह फाइल के तहत है> परियोजना संरचना, फिर यह ड्रॉपडाउन। उम्मीद है कि यह मदद करता है!

एनवीएम, पर्याप्त प्रतिष्ठा नहीं है। लेकिन मैंने विवरण दिया।

+0

चित्र पोस्ट करने के लिए पर्याप्त प्रतिष्ठा * – Jahhein

+0

आप हमेशा कुछ छवि होस्टिंग सर्वर में छवि पोस्ट कर सकते हैं और लिंक साझा कर सकते हैं। उच्च प्रतिष्ठा वाले अन्य उपयोगकर्ता आपकी पोस्ट को सीधे आपके उत्तर में चित्र शामिल करने के लिए संपादित कर सकते हैं। – Pshemo

+0

धन्यवाद, मैं तब तक इंतजार करूंगा जब तक कि मेरे पास 10 प्रतिष्ठा न हो। मुझे लगता है कि निर्देश सीधे आगे हैं। मैं लैम्ब्डा के बारे में बहुत सारे प्रश्न देख रहा हूं, और आमतौर पर इसका जवाब है। – Jahhein

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