2017-11-03 50 views
12

मैं यह समझने की कोशिश कर रहा हूं कि Comparator.comparing फ़ंक्शन कैसे काम करता है। मैंने इसे समझने के लिए अपनी तुलनात्मक विधि बनाई।जावा लैम्ब्डा तुलनित्र रूपांतरण के लिए - मध्यवर्ती प्रतिनिधित्व

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) { 
    BiFunction<T,T,Integer> bfun = (T a, T b) -> f.apply(a).compareTo(f.apply(b)); 
    return (Comparator<T>) bfun; 
} 

इस फ़ंक्शन में अंतिम पंक्ति अपवाद फेंकता है।

हालांकि, अगर मैं

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) { 
    return (T a, T b) -> f.apply(a).compareTo(f.apply(b)); 
} 

को यह समारोह बदल यह ठीक अपेक्षा के अनुरूप काम करता है।

मध्यवर्ती कार्यात्मक इंटरफ़ेस क्या है जो दूसरा प्रयास उपयोग करता है, जो लैम्ब्डा को Comparator में परिवर्तित करने में सक्षम है?

+4

जिस प्रकार का लैम्ब्डा परिवर्तित होता है वह प्रकार है जिस प्रकार अभिव्यक्ति इसके संदर्भ से होनी चाहिए। पहले उदाहरण में लैम्ब्डा को 'बायफंक्शन' में परिवर्तित करना होगा क्योंकि यह उस वैरिएबल का प्रकार है जिसे इसे सौंपा गया है। दूसरे उदाहरण में लैम्ब्डा को 'तुलनाकर्ता' में परिवर्तित करना होगा क्योंकि यह विधि का रिटर्न प्रकार है। 'बायफंक्शन 'और' तुलनाकर्ता 'के समान" आकार "है, इसलिए वही लैम्ब्डा या तो संदर्भ के आधार पर हो सकता है, लेकिन वे अलग-अलग प्रकार हैं इसलिए एक दूसरे को कास्टिंग करना असफल हो जाएगा। –

+0

मैं इसे कम कर रहा हूं। गुणवत्ता के लिए नहीं, लेकिन क्योंकि इस प्रश्न पर कई लेखापरीक्षाएं थीं, जिनमें से * तीन * विफल रहे। –

उत्तर

11

मध्यवर्ती कार्यात्मक इंटरफ़ेस क्या है जो दूसरा प्रयास उपयोग करता है, जो लैम्ब्डा को तुलनात्मक में परिवर्तित करने में सक्षम है?

Comparator स्वयं।

दूसरी विधि के भीतर, आपने Comparator परिभाषित किया है, एक मध्यवर्ती वस्तु नहीं है जिसे Comparator पर डाला गया है।

इस फ़ंक्शन में अंतिम पंक्ति अपवाद फेंकता है।

हां, यह चाहिए।

यदि दो वर्ग कार्यात्मक इंटरफेस हैं और समान विधियां हैं (समान हस्ताक्षर और समान वापसी प्रकार के साथ), इसका मतलब यह नहीं है कि इन्हें एक दूसरे के लिए उपयोग किया जा सकता है। -


एक दिलचस्प चाल आप BiFunction<T, T, Integer> bfun की विधि apply का हवाला देते हुए एक Comparator<T> कर सकते हैं:

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) { 
    final BiFunction<T,T,Integer> bfun = (T a, T b) -> f.apply(a).compareTo(f.apply(b)); 
    return bfun::apply; // (a, b) -> bfun.apply(a, b); 
} 
5

अपने दूसरे प्रयास में मध्यवर्ती कार्यात्मक इंटरफ़ेस बस Comparator<T> है:

आप इसे देख सकते हैं क्योंकि आपका कोड-स्निपेट निम्न के बराबर है:

private static <T,U extends Comparable<U>> Comparator<T> comparing(Function<T,U> f) { 
    Comparator<T> comparator = (T a, T b) -> f.apply(a).compareTo(f.apply(b)); 
    return comparator; 
} 
संबंधित मुद्दे