2014-04-17 13 views
6

के बजाय विधि संदर्भ का उपयोग करना मैं "विशेष प्रकार के मनमानी वस्तु के एक उदाहरण विधि के संदर्भ में" अवधारणा के बारे में उलझन में हूं। ओरेकल documentation इस बारे में एक उदाहरण है:बहु तर्क lambda

String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" }; 
Arrays.sort(stringArray, String::compareToIgnoreCase); 

उदाहरण मैं विधि संदर्भ के इस प्रकार के लिए देखा है में से अधिकांश इस तरह है: अगर लैम्ब्डा की तरह है: x -> x.func() तो आप इसके ClassOfX::func तरह लिख सकते हैं। दस्तावेज में उदाहरण का कहना है:

विधि संदर्भ स्ट्रिंग के लिए बराबर लैम्ब्डा अभिव्यक्ति :: compareToIgnoreCase औपचारिक पैरामीटर सूची (स्ट्रिंग एक, स्ट्रिंग ख) है, जहां एक और ख मनमाने ढंग से बेहतर करने के लिए इस्तेमाल नाम हैं होता इस उदाहरण का वर्णन करें। विधि संदर्भ विधि a.compareToIgnoreCase (बी) का आह्वान करेगा।

सवाल यह है: किसी भी दो तर्क लैम्ब्डा (a, b) -> a.func(b) तरह func विधि उदाहरण पहला तर्क और लैम्ब्डा का दूसरा तर्क की विधि होना चाहिए के लिए है कि विधि के लिए एक तर्क के रूप पारित हो जाएगा? यदि हमारे पास एकाधिक तर्क लैम्ब्डा है तो func विधि लैम्ब्डा के पहले तर्क की विधि विधि होनी चाहिए और लैम्ब्डा के अन्य तर्कों को लैम्ब्डा में दिखाई देने के क्रम में func पर भेजा जाएगा? मेरा मतलब है (a, b, c) -> a.func(b, c) के बजाय हम ClassOfA::func

मुझे अपनी अंग्रेजी के लिए खेद है। मुझे आशा है कि मैंने समस्या को स्पष्ट कर दिया है।

उत्तर

11

SomeClass::funcfunc एक स्थिर विधि या एक उदाहरण विधि के आधार पर दो चीजों का मतलब हो सकता है।

(1) यदि func एक स्थिर तरीका है, तो SomeClass::func एक लैम्ब्डा कि सिर्फ विधि करने के लिए सभी तर्कों से गुजरता है:

(a, b, c) -> SomeClass.func(a, b, c); 

(2) यदि func एक उदाहरण विधि है, तो SomeClass::func एक है लैम्ब्डा उदाहरण के रूप में पहला तर्क का उपयोग करता है, जैसा कि आप सोचा:

(a, b, c) -> a.func(b, c); 

a टाइप SomeClass है जहां।

संपादित करें: सोटीरिओस 'जवाब अभी तक विधि संदर्भ की एक अलग प्रकार दर्शाता है: example::method जहां example एक संदर्भ चर (बजाय एक वर्ग के नाम) है। इस रूप में

(a, b) -> example.method(a, b); 

या शायद अधिक सही ही मतलब है

(a, b) -> __someFinalTemporary.method(a, b); 

जहां __someFinalTemporary बिंदु है जहां विधि संदर्भ मूल्यांकन किया जाता है पर example को सौंपा गया है, ताकि यदि example परिवर्तन बाद में, पद्धति अभी भी है example के पहले मान का उपयोग करके बुलाया जाता है।

[चौथा प्रकार SomeClass::new है जो एक निर्माता को तर्क देता है। मुझे लगता है कि यह सब है।]

+1

+1 पूरी तरह से होने के लिए। –

3

मैं बजाय (ए, बी, सी) मतलब -> a.func (ख, ग) हम लिख सकते हैं ClassOfA :: समारोह

हां, यह सही है।

7

यहां एक छोटा सा उदाहरण है जो एक उदाहरण विधि संदर्भ के व्यवहार का प्रदर्शन करता है।

public class Example { 
    public static void main(String[] args) throws Exception { 
     List<String> strings = new ArrayList<String>(); 
     Example example = new Example(); 
     Functional methodRef = example::method; 
     methodRef.funct("a string", strings); 
     System.out.println("List now contains: " + strings); 

     Functional lambda = (String s, List<String> l) -> { 
      example.method(s, l); 
     }; 
     lambda.funct("another string", strings); 
     System.out.println("List now contains: " + strings); 
    } 

    interface Functional { 
     void funct(String value, List<String> list); 
    } 

    void method(String value, List<String> toAddTo) { 
     System.out.println("adding"); 
     toAddTo.add(value); 
    } 
} 

यह प्रिंट

adding 
List now contains: [a string] 
adding 
List now contains: [a string, another string] 

दो कम या ज्यादा बराबर हैं। लैम्ब्डा के मामले में, परिवर्तनीय विधि प्रभावी ढंग से final होने की आवश्यकता पर लागू की जाती है।

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