इस विधि को देखते हुए:

private static Integer getVal(Integer a, Integer b){
   return a + b;
}

जिसे लैम्ब्डा कहा जा सकता है:

a -> getVal(1, 2)

क्या इसे किसी विधि संदर्भ में बदलने का कोई तरीका है, जैसे कुछ:

Class::getVal

धन्यवाद

1
user1052610 27 पद 2017, 10:48
4
आपको क्यों लगता है कि आपको इसकी आवश्यकता है?
 – 
shmosel
27 पद 2017, 11:44

3 जवाब

ठीक है, यदि आप विधि कॉल में स्थिरांक पास कर रहे हैं, तो आप एक और विधि बना सकते हैं जो मूल विधि को कॉल करती है:

private static Integer getVal (Integer a) {
    return getVal(1,2);
}

तो आप दूसरी विधि के लिए विधि संदर्भ का उपयोग कर सकते हैं।

यानी आप बदल सकते हैं

a -> getVal(1, 2)

प्रति

ClassName::getVal

उस ने कहा, इसका ज्यादा मतलब नहीं है।

पीएस, यह स्पष्ट नहीं है कि आपके लैम्ब्डा अभिव्यक्ति में a का उद्देश्य क्या है, क्योंकि आप इसे अनदेखा कर रहे हैं।

आम तौर पर आप किसी दिए गए विधि के विधि संदर्भ को पास कर सकते हैं यदि यह आवश्यक कार्यात्मक इंटरफ़ेस की एकल विधि के हस्ताक्षर से मेल खाता है।

उदाहरण:

public static Integer apply (BinaryOperator<Integer> op, Integer a, Integer b)
{
    return op.apply(a,b);
}

अब आप कॉल कर सकते हैं:

apply(ClassName::getVal)

अपने मूल तरीके से।

2
Eran 27 पद 2017, 11:06
धन्यवाद। यह वास्तव में सवाल है - लैम्ब्डा को पूर्णांक मान कैसे पास करें, जैसे: (val1, val2) -> getVal(val1, val2)
 – 
user1052610
27 पद 2017, 10:58
यह निर्भर करता है कि आप अपना विधि संदर्भ कहां दे रहे हैं। यदि आप इसे किसी ऐसी विधि में पास कर रहे हैं जिसके लिए एक कार्यात्मक इंटरफ़ेस की आवश्यकता होती है जिसमें 2 तर्कों वाली विधि होती है, तो आप अपनी मूल विधि पास कर सकते हैं।
 – 
Eran
27 पद 2017, 11:03
इसे Map.computeIfAbsent() के दूसरे तर्क में पास किया जा रहा है। तो मुझे जो चाहिए वह है map.computeIfAbsent("xxx", Class:getVal)
 – 
user1052610
27 पद 2017, 11:06
computeIfAbsent() का दूसरा तर्क एक Function<? super K, ? extends V> लेता है, इसलिए इसे एक तर्क के साथ एक विधि की आवश्यकता होती है, दो नहीं।
 – 
Eran
27 पद 2017, 11:08
क्या होगा यदि पहला तर्क ऑब्जेक्ट रैपर था जिसमें दो मान होते हैं। क्या इस तरह से गुजरना संभव होगा?
 – 
user1052610
27 पद 2017, 11:10

यहाँ एक उदाहरण है।

interface Operator {
    int operate(int a, int b);
}

class Calc {
    public static int add(int a, int b) {
        return a + b;
    }
}

class Main {    
    public static void main(String[] args) {
        // using method reference
        int result = operate(1, 2, Calc::add);
        // using lambda
        int result = operate(1, 2, (a, b) -> Calc.add(a, b));
    }

    static int operate(int a, int b, Operator operator) {
        return operator.operate(a, b);
    }
}

विधि संदर्भ का उपयोग करने के लिए आपको एक कार्यात्मक इंटरफ़ेस की आवश्यकता है (इस उदाहरण में Operator)। और आपको एक ऐसी विधि की भी आवश्यकता है जो कार्यात्मक इंटरफ़ेस के एक उदाहरण को उसके परमाटर के रूप में स्वीकार करे (इस उदाहरण में operate(int a, int b, Operator operator)।

अपडेट करें

यदि आपको ऑब्जेक्ट रैपर की आवश्यकता है, तो बस operate विधि को बदल दें

static int operate(ObjectWrapper wrapper, Operator operator) {
    return operator.operate(wrapper.getA(), wrapper.getB());
}

और फिर operate विधि को कॉल करें:

int result = operate(wrapper, Calc::add);
2
zhh 27 पद 2017, 11:43

GetVal() केवल एक विधि संदर्भ के रूप में प्रयोग करने योग्य होगा, उन जगहों पर जहां एक लागू प्रकार का कार्यात्मक इंटरफ़ेस अपेक्षित है, जैसे BiFunction या IntBinaryOperator, या एक कस्टम कार्यात्मक इंटरफ़ेस (जैसा कि उत्तर)

उदाहरण:

    public static void main(String[] args) {
        Integer result1 = calculate(1, 2, Second::getVal);
        Integer result2 = calculateAsInt(1, 2, Second::getVal);
    }

    private static Integer getVal(Integer a, Integer b){
        return a + b;
    }

    private static Integer calculate(Integer a, Integer b, BinaryOperator<Integer> operator) {
        return operator.apply(a, b);
    }

    private static int calculateAsInt(int a, Integer b, IntBinaryOperator operator) {
        return operator.applyAsInt(a, b);
    }
1
Ward 27 पद 2017, 11:41