简体   繁体   中英

How to take 2 maximum values if HashMap key is equal in Java

I have a HashMap and I want to take two maximum values from it. I used following code. But ,if HashMap key is equal it don't give correct value. So, How to take correct values?

import java.util.LinkedHashMap;
import java.util.Map;

public class TakeTwoMaximumAndChange {
    public static void main(String[] args) {
        TakeTwoMaximumAndChange ob = new TakeTwoMaximumAndChange();
        ob.test();
    }

    public void test() {
        LinkedHashMap<String, Double> data = new LinkedHashMap<String, Double>();
        data.put("a", 2.3);
        data.put("b", 2.5);
        data.put("c", 8.3);
        data.put("d", 3.8);
        data.put("c", 6.3);
        data.put("f", 4.4);

        Map.Entry<String, Double> max1 = null;
        Map.Entry<String, Double> max2 = null;

        // searching the first biggest value
        for (Map.Entry<String, Double> en : data.entrySet()) {
            if (max1 == null || en.getValue().compareTo(max1.getValue()) > 0) {
                max1 = en;
            }
        }
        System.out.println(max1);

        // searching the second biggest value
        for (Map.Entry<String, Double> en : data.entrySet()) {
            if (en != max1
                    && (max2 == null || (en.getValue().compareTo(max2.getValue())) > 0)) {
                max2 = en;
            }
        }
        System.out.println(max2);
    }
}

The quick answer is

// searching the first and second biggest value at once
        for (Map.Entry<String, Double> en : data.entrySet()) {
            if (max1 == null || en.getValue().compareTo(max1.getValue()) > 0) {
                  max2= max1;
                  max1 = en;

            }
        }

However this fails if the first entry tested is the max(thanks for pointing this out, @Grayson)

// searching the first and second biggest value at once, corrected
        for (Map.Entry<String, Double> en : data.entrySet()) {

            if (max1 == null){
                  max1 = en;
            }else if (en.getValue().compareTo(max1.getValue()) > 0) {
                  max2= max1;
                  max1 = en;

            }else if ( (max2 == null) || (en.getValue().compareTo(max2.getValue()) > 0) ){
                  max2 = en;
            }
        }

Your problems is not about your algorithm. This is because a Map does NOT accept duplicated keys.

LinkedHashMap<String, Double> data = new LinkedHashMap<String, Double>();
data.put("c", 8.3);
data.put("c", 6.3); // The second value replace the first one in the Map



Note: Unrelated to the problem , but if you are using Java 8, you might consider using lambda, which i think are much more readable:

Map<String, Double> m = new HashMap<>();        

final Map.Entry<String, Double> max = m.entrySet()
    .stream()
    .max((o1, o2) -> o1.getValue().compareTo(o2.getValue())) // find the max
    .get();

final Map.Entry<String, Double> max2 = m.entrySet()
    .stream()
    .filter((e) -> !e.getKey().equals(max.getKey())) // remove the first max
    .max((o1, o2) -> o1.getValue().compareTo(o2.getValue()))
    .get();

我不能直接使用HashMap.So,我对HAshMap值进行排序,然后将值添加到ArrayList,并将列表的最后2个值作为最大2个值。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM