2014-10-12 21 views
6

मेरे पास नक्शा Map<String, List<Double> है और मैं सभी सूचियों में अधिकतम (या न्यूनतम) मान प्राप्त करना चाहता हूं। फ़ंक्शन को अधिकतम (या न्यूनतम) मान और उस मान से संबंधित कुंजी वापस करनी चाहिए।जावा 8 हैश मानचित्र

हस्ताक्षर

public static Pair<String,Double> getKeyValue(Map<String, List<Double>> map, BinaryOperator<Double> function)

जो नक्शे और समारोह Double::max या Double::min

कैसे मैं इस कुशलता से (और खूबसूरती से) लागू कर सकते हैं जावा 8 का उपयोग कर, धारा एपीआई हो जाता है हो सकता है?

उत्तर

4

BinaryOperator उस कार्य के लिए एक अच्छा विनिर्देश नहीं है, यह उचित मूल्य उत्पन्न करने में कमी में उपयोग करने के लिए सीधे आगे है, उदाहरण के लिए न्यूनतम या अधिकतम, हालांकि यह Map के प्रमुख मान जैसे संबंधित मान को वापस करने के लिए उपयुक्त नहीं है। इसका उपयोग इस प्रकार से तात्पर्य है कि कार्यान्वयन को कम करने के दौरान सही कुंजी मान का चयन करने के लिए वास्तव में क्या किया गया था, BinaryOperator क्या पता लगाने के लिए अतिरिक्त संचालन करना है। इससे भी बदतर, यह गारंटी नहीं दे सकता कि BinaryOperator ऐसा कुछ करता है जो इस प्रकार की कमी को करने की अनुमति देता है, उदा। ऑपरेटर एक ऐसा मूल्य वापस कर सकता है जो उसके तर्कों में से न हो।

ऐसे कार्य के लिए, Comparator बेहतर विकल्प है क्योंकि यह ऑर्डरिंग निर्दिष्ट करने और अधिकतम और न्यूनतम खोजने जैसे संबंधित संचालन करने के लिए डिज़ाइन किया गया है। एक कार्यान्वयन इस प्रकार दिखाई देंगे:

public static Pair<String,Double> getMinimumKeyValue(
    Map<String, List<Double>> map, Comparator<Double> function) { 

    return map.entrySet().stream() 
     .map(e->new Pair<>(e.getKey(), e.getValue().stream().min(function).get())) 
     .min(Comparator.comparing(Pair::getRight, function)).get(); 
} 

यह getMinimumKeyValue नाम पर है के रूप में यह कम से कम मुख्य/मान जोड़े लौटने जब आप Comparator.naturalOrder() में पारित करेंगे।

लेकिन आप अधिकतम Comparator.reverseOrder() पास करके भी प्राप्त कर सकते हैं।

और यह उपयोग के मामलों का एक व्यापक रेंज का समर्थन करने के संशोधित करने के लिए आसान है:

public static <K,V> Pair<K,V> getMinKeyValue(
    Map<K, ? extends Collection<V>> map, Comparator<? super V> function) { 

    return map.entrySet().stream() 
     .map(e->new Pair<>(e.getKey(), e.getValue().stream().min(function).get())) 
     .min(Comparator.comparing(Pair::getRight, function)).get(); 
} 

यह अभी भी एक Pair<String,Double> एक Map<String, List<Double>> से बाहर हो रही के लिए काम करता है लेकिन एक बहुत अधिक कर सकते हैं ...

4

आप इस कोशिश कर सकते हैं:

public static Pair<String,Double> getKeyValue(Map<String,List<Double>> map, 
     BinaryOperator<Double> function) { 
     return map.entrySet().stream() 
      .map(e -> new Pair<String,Double>(e.getKey(),e.getValue().stream().reduce(function).get())) 
      .reduce((p1,p2) -> function.apply(p1.getValue(),p2.getValue()).equals(p1.getValue()) ? p1 : p2) 
      .get(); 
} 

स्पष्टीकरण:

सबसे पहले, आप प्रत्येक Entry<String,List<Double>> एक Pair<String,Double> जहां मूल्य मिनट (या अधिकतम) सूची की और महत्वपूर्ण अवशेष है सहयोगी वही, तो आप सबसे कम (या उच्चतम) मान वाले किसी को खोजने के लिए प्रत्येक Pair<String,Double> की तुलना करें।

+2

आप उपयोग कर रहे हैं '==' बॉक्सिंग 'डबल' पर, जो अपेक्षा के अनुसार काम करने की संभावना नहीं है। मैं 'बाइनरीऑपरेटर ' दृष्टिकोण से दूर जाने की कोशिश करता हूं और 'तुलनाकर्ता' पसंद करता हूं .... –

+0

यह सही है, लेकिन मैं इसे ठीक करने के लिए परीक्षण को 'a.equals (b)' में बदल दूंगा । यह ध्यान देने के लिए धन्यवाद! – Dici

+0

मैं वास्तव में इसे पढ़ नहीं सकता। शायद यह सिंटैक्स है, लापता जोड़ी अक्षर, जो भी हो, लेकिन मुझे हास्केल पढ़ने में कम समस्याएं थीं। आम तौर पर, जावा में सादे पुरानी शैली की तुलना में कार्यात्मक दृष्टिकोण अक्सर बहुत कम पठनीय होता है। –

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