2016-11-09 8 views
8

देता है, लेकिन यह मुझे एक संकलक त्रुटि देता हैतुलना और thenComparing मैं नाम तो Java8 <code>Comparator</code> उपयोग करके आयु द्वारा कर्मचारियों की <code>List</code> सॉर्ट करने के लिए कोशिश कर रहा हूँ, मैं <code>Comparator</code> नीचे बनाया है संकलन त्रुटि

Type mismatch: cannot convert from Comparator<Object> to <unknown>

Comparator<String> c = Comparator.comparing(s -> s.split("\\s+")[0]) 
      .thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1])); //compile error 

लेकिन यह काम करता है अगर मैं स्पष्ट रूप से टाइप

निर्दिष्ट करता हूं

या

Comparator<String> name = Comparator.comparing(s -> s.split("\\s+")[0]); 
    Comparator<String> age = Comparator.comparingInt(s -> Integer.parseInt(s.split("\\s+")[1])); 
    Comparator<String> cc = name.thenComparing(age); //works 

मैं बाईं ओर प्रकार Comparator<String> निर्दिष्ट किया है दो Compartor रों बनाने और श्रृंखला लेकिन क्यों ऑटो प्रकार निष्कर्ष सही प्रकार नहीं मिल रहा है और स्पष्ट रूप से निर्दिष्ट करने की उम्मीद है।

क्या कोई इस पर स्पष्टीकरण दे सकता है?

यहाँ कोड

String[] arr = { "alan 25", "mario 30", "alan 19", "mario 25" }; 
    Comparator<String> c = Comparator.<String, String> comparing(s -> s.split("\\s+")[0]) 
      .thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1])); 
    List<String> sorted = Arrays.stream(arr).sorted(c).collect(Collectors.toList()); 
    System.out.println(sorted); 

उत्पादन

[alan 19, alan 25, mario 25, mario 30] 
+0

मैं सामान्य प्रकार निष्कर्ष पर एक विशेषज्ञ नहीं हूँ, लेकिन मेरा अनुमान है कि यह सिर्फ "बहुत ज्यादा ऑटो अनुमान है।" शायद, यह 'तुलना()' विधि के प्रकार को नहीं समझ सकता है क्योंकि इसमें किसी भी प्रकार का "एंकर" नहीं है, जो कि चेनिंग विधि के विपरीत है जहां आप स्पष्ट रूप से 'तुलना करने के परिणामस्वरूप एक प्रकार देते हैं () '। भले ही, मुझे लगता है कि यह आपके स्वयं के 'तुलनाकर्ता' लिखने के लिए और अधिक पठनीय होगा, और केवल एक बार 'स्प्लिट' कॉल करें। सबसे कम संभव लाइनों में कोड निचोड़ने के लिए कोई पुरस्कार नहीं है। – ajb

+1

लक्षित टाइपिंग जंजीर विधि आमंत्रण के माध्यम से काम नहीं करती है, [यहां] देखें (http://stackoverflow.com/a/28834656/2711488) और [यहां] (http://stackoverflow.com/a/26883991/2711488) और [यहां] (http://stackoverflow.com/a/31383947/2711488)। हालांकि, आप बस अपने दो चरण तुलनित्र के बजाय 'Comparator.comparing (s -> s.replaceFirst ("\\ s +", "")) का उपयोग कर सकते हैं और परिणाम वही होगा ... – Holger

+0

'Comparator.comparing ((स्ट्रिंग एस) -> s.split ("\\ s +") [0])। फिर कॉम्पैरिंगइन्ट (एस -> Integer.parseInt (एस।विभाजन ("\\ s +") [1])) 'काम करता है लेकिन यह' स्ट्रिंग 'क्यों आवश्यक है, यह' तुलनाकर्ता 'से अनुमान लगा सकता है, क्या यह प्रकार अनुमान में एक सीमा है? 'जावा संस्करण' का उपयोग कर बीटीडब्ल्यू 1.8.0_60 "' – Saravana

उत्तर

2

जावा सभी चर का एक प्रकार है पता करने के लिए की जरूरत है। कई lambdas में यह एक प्रकार का अनुमान लगा सकता है, लेकिन आपके पहले कोड स्निपेट में, यह s के प्रकार का अनुमान नहीं लगा सकता है। मुझे लगता है कि समस्या को हल करने के लिए मानक तरीका यह स्पष्ट रूप से घोषित करने के लिए होगा:

Comparator<String> c = Comparator.comparing((String s) -> s.split("\\s+")[0]) 
      .thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1])); 

आप this answer को देखें, तो यह Comparator.comparing() के तर्क में एक समान प्रकार घोषणा की है।

आपकी विधि, स्पष्ट रूप से comparing() के प्रकार के तर्क देकर, स्पष्ट रूप से भी काम करती है।

दो अन्य तुलनित्रों की घोषणा करते हुए, आपकी अन्य विधि के लिए, मुझे पूरा भरोसा है कि इस मामले में जावा असाइनमेंट के बाईं ओर String से अनुमान लगा सकता है, जैसे परंपरागत List <String> = new ArrayList<>(); में। जब आप एक ही अभिव्यक्ति में thenComparing() पर कॉल करने के लिए जाते हैं, तो जावा अब नहीं देख सकता है कि बाएं तरफ से प्रकार प्रासंगिक है। यह थोड़ा int size = new ArrayList<>().size(); की तरह यह भी काम करता है होगा:

Comparator<String> name = Comparator.comparing(s -> s.split("\\s+")[0]); 
    Comparator<String> c = name.thenComparingInt(s -> Integer.parseInt(s.split("\\s+")[1])); 
+1

@ ole-vv Comparator.comparing ((स्ट्रिंग एस) -> s.split ("\\ s +") [0])। फिर कॉम्पैरिंगइन्ट (एस -> Integer.parseInt (s.split ("\\ s +") [1])) काम करता है लेकिन यह स्ट्रिंग क्यों है आवश्यक है, यह तुलनात्मक से अनुमान लगा सकता है, क्या यह प्रकार अनुमान में एक सीमा है? जावा संस्करण का उपयोग कर बीटीडब्ल्यू "1.8.0_60" – Saravana

+2

आप इसका अनुमान कैसे लगाते हैं? आप जानते हैं कि 'तो समेकन()' को 'तुलनाकर्ता ' (असाइनमेंट के बाएं हाथ के पक्ष में फिट करने के लिए) वापस करना चाहिए, इसलिए तुलनात्मक() 'को 'कंप्रेसर ' वापस करने की आवश्यकता है, इसलिए' s 'को एक होना चाहिए 'स्ट्रिंग'। संकलक तर्क के इस कई चरणों से गुजरता नहीं है। हां, यह प्रकार अनुमान में एक सीमा है, लेकिन मुझे लगता है कि यह एक उद्देश्य उद्देश्य पर पेश किया गया है क्योंकि अन्यथा नियम बहुत जटिल हो जाएंगे और प्रोग्रामर उन्हें समझ नहीं पाएंगे। यह मेरा सबसे अच्छा अनुमान है। –

+1

सबसे बड़ी समस्या यह है कि जंजीर चालान के माध्यम से लक्षित टाइपिंग बाद के आमंत्रण के लिए उपलब्ध विधियों को बदल सकती है, जिसका उपयोग वास्तव में पिछले 'लक्ष्य प्रकार, यानी' foo (x) .bar (y) ', वापसी के साथ किया जाता था 'foo (x)' का प्रकार निर्धारित करता है कि कौन सा और कौन सा बार (...) 'विधियां उपलब्ध हैं, लेकिन 'foo (x)' पर लक्ष्य टाइपिंग लागू करना वास्तव में चयनित 'बार (...)' विधि पर निर्भर करता है। – Holger

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

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