लेकिन, ::
ऑपरेटर का वास्तव में क्या अर्थ है? खैर, ::
ऑपरेटर इस तरह वर्णित किया जा सकता (this SO question से):
विधि संदर्भ विभिन्न शैलियों में प्राप्त किया जा सकता है, लेकिन वे सभी एक ही मतलब है:
- एक स्थिर विधि (
ClassName::methodName
)
- एक विशेष वस्तु का एक उदाहरण विधि (
instanceRef::methodName
)
- एक विशेष वस्तु के लिए एक सुपर विधि (
super::methodName
)
- एक विशेष प्रकार का एक मनमाना वस्तु का एक उदाहरण विधि (
ClassName::methodName
)
- एक वर्ग निर्माता संदर्भ (
ClassName::new
)
- एक सरणी निर्माता संदर्भ (
TypeName[]::new
)
तो, विधि है कि इसका मतलब है कि संदर्भ String::compareToIgnoreCase
दूसरी श्रेणी (instanceRef::methodName
) के अंतर्गत आता है जिसका अर्थ है कि इसका अनुवाद (a, b) -> a.compareToIgnoreCase(b)
पर किया जा सकता है।
मुझे विश्वास है कि निम्नलिखित उदाहरण आगे बताते हैं। Comparator<String>
में एक विधि है जो दो String
ऑपरेटरों पर संचालित होती है और int
लौटाती है। इसे छद्म-वर्णित किया जा सकता है (a, b) ==> return int
(जहां ऑपरेंड a
और b
हैं)। आप इसे इस तरह से उस श्रेणी के अंतर्गत निम्नलिखित फॉल्स के सभी देखते हैं:
// Trad anonymous inner class
// Operands: o1 and o2. Return value: int
Comparator<String> cTrad = new Comparator<String>() {
@Override
public int compare(final String o1, final String o2) {
return o1.compareToIgnoreCase(o2);
}
};
// Lambda-style
// Operands: o1 and o2. Return value: int
Comparator<String> cLambda = (o1, o2) -> o1.compareToIgnoreCase(o2);
// Method-reference à la bullet #2 above.
// The invokation can be translated to the two operands and the return value of type int.
// The first operand is the string instance, the second operand is the method-parameter to
// to the method compareToIgnoreCase and the return value is obviously an int. This means that it
// can be translated to "instanceRef::methodName".
Comparator<String> cMethodRef = String::compareToIgnoreCase;
This great SO-answer to explains how lambda functions are compiled। उस उत्तर में Jarandinor ब्रायन गोएट्ज़ उत्कृष्ट दस्तावेज़ से निम्नलिखित मार्ग को संदर्भित करता है जो more about lambda translations का वर्णन करता है।
इसके बजाय उद्देश्य यह है कि (जैसे एक आंतरिक वर्ग के लिए एक निर्माता बुला के रूप में) लैम्ब्डा अभिव्यक्ति लागू करता है बनाने के लिए बाईटकोड पैदा करने की
, हम लैम्ब्डा के निर्माण के लिए एक नुस्खा का वर्णन है, और भाषा रनटाइम के लिए वास्तविक निर्माण प्रतिनिधि। यह नुस्खा एक invokedynamic निर्देश की स्थिर और गतिशील तर्क सूचियों में एन्कोड किया गया है।
मूल रूप से इसका अर्थ यह है कि मूल रनटाइम तय करता है कि लैम्ब्डा का अनुवाद कैसे करें।
ब्रायन जारी है:
विधि संदर्भ, लैम्ब्डा अभिव्यक्ति के रूप में एक ही तरह से व्यवहार कर रहे हैं, सिवाय इसके कि सबसे विधि संदर्भ एक नई पद्धति में desugared किए जाने की जरूरत नहीं है, हम संदर्भित विधि के लिए बस एक स्थिर विधि हैंडल लोड कर सकते हैं और मेटाफैक्टरी को पास कर सकते हैं।
तो, lambdas एक नई विधि में desugared हैं। जैसे
class A {
public void foo() {
List<String> list = ...
list.forEach([lambda for lambda$1 as Consumer]);
}
static void lambda$1(String s) {
System.out.println(s);
}
}
लेकिन, ब्रायन इस दस्तावेज़ में बताते हैं::
class A {
public void foo() {
List<String> list = ...
list.forEach(s -> { System.out.println(s); });
}
}
कोड ऊपर कुछ इस तरह के desugared हो जाएगा
अगर desugared विधि एक उदाहरण है विधि, रिसीवर को पहला तर्क माना जाता है
ब्रायन ने स्पष्टीकरण जारी रखा है कि लैम्ब्डा के शेष तर्कों को संदर्भित विधि पर तर्क के रूप में पारित किया गया है।
तो, this entry by Moandji Ezana की मदद से, एक Comparator<String>
रूप compareToIgnoreCase
की desugaring नीचे निम्न चरणों का पालन करने के लिए तोड़ा जा सकता है:
- एक
List<String>
के लिए Collections#sort
उम्मीद एक Comparator<String>
Comparator<String>
के साथ एक कार्यात्मक इंटरफ़ेस है विधि int sort(String, String)
, जो BiFunction<String, String, Integer>
- के बराबर है तो तुलनित्र उदाहरणद्वारा प्रदान किया जा सकता हैसंगत लैम्ब्डा:
(String a, String b) -> a.compareToIgnoreCase(b)
String::compareToIgnoreCase
एक उदाहरण विधि है कि एक String
तर्क कहलाता है, तो यह ऊपर लैम्ब्डा साथ संगत है: String a
रिसीवर हो जाता है और String b
विधि तर्क
संपादित हो जाता है: `तुलनाकारी <: ओपी से इनपुट के बाद मैं एक निम्न स्तर उदाहरण है कि desugaring
दिलचस्प सवाल बताते हैं शायद और भी स्पष्ट उदाहरण जोड़ लिया है,? सुपर स्ट्रिंग> cmp = स्ट्रिंग :: तुलना करें IgnoreCase; 'ईमानदारी से, मुझे नहीं पता कि यह कैसे काम करता है। – MightyPork
मेरा मानना है कि इसे http://stackoverflow.com/questions/20001427/double-colon-operator-in-java-8 – MightyPork