简体   繁体   中英

java: sort hashmap by keys and values

I want sort a hash map by keys and values. Currently, i have sorted the map by values but the key contains String which i want to sort without disturbing the previously sorted map by values?

map after sorting by values

{Login to new=27, Failed login=27, Impossible=21}

How i want to sort map

{Failed login =27, Login to new =27, Impossible =21}

I have tried sorting by values first and then keys but failed in achieving what i needed.

PS i am very new to java

edit: Adding sorting function which i took it from stack overflow

    public static <K, V extends Comparable<? super V>> Map<K, V
    sortByValue(Map<K, V> map) {
    List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
        @Override
        public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) {
            return (e2.getValue()).compareTo(e1.getValue());
        }
    });
    Map<K, V> result = new LinkedHashMap<>();
    for (Map.Entry<K, V> entry : list) {
        result.put(entry.getKey(), entry.getValue());
    }
    return result;
}

you can write your own comparator like below -

class MapValueKeyComparator<K extends Comparable<? super K>, V extends Comparable<? super V>>
        implements Comparator<Map.Entry<K, V>> {

    public int compare(Map.Entry<K, V> a, Map.Entry<K, V> b) {
        int cmp1 = b.getValue().compareTo(a.getValue()); //can reverse a and b position for ascending/descending ordering
        if (cmp1 != 0) {
            return cmp1;
        } else {
            return a.getKey().compareTo(b.getKey()); //can reverse a and b position for ascending/descending ordering
        }
    }

}

Put all the map entries in the list and sort them -

  HashMap<String, Integer> map = new HashMap<String, Integer> ();

    map.put("Login to new", 27);
    map.put("Failed login", 27);
    map.put("Impossible", 21);

  List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
   Collections.sort(list, new MapValueKeyComparator<String, Integer>());

  for(Map.Entry<String, Integer> m : list){
     System.out.println(m);
  }

Output -

Failed login=27 Login to new=27 Impossible=21

Explanation - MapValueKeyComparator sorts key and value of a given map, where values are sorted first and then the keys. In the main code putting all the map entries in the list so that it can be sorted using this comparator by using java's Collections util class.

You can sort the contents of a Map the way you describe; however, the output will be a List, that is, a sorted List. You will then need to process the list to get your desired output.

This code should do what you want:

    Comparator<Entry<String, Integer>> byKeyThenByValue = Comparator.comparing(
            entry -> entry.getKey() + entry.getValue());

    List<Entry<String, Integer>> outList = mymap.entrySet().stream()
            .peek(entry -> System.out.println("K: " + entry.getKey() + "  v: " + entry.getValue()))
            .sorted(byKeyThenByValue)
            .collect(Collectors.toList());
    System.out.println(outList);

    Map<Object, Object> outMap = new LinkedHashMap<>();
    outList.forEach(entry -> outMap.put(entry.getKey(), entry.getValue()));
    System.out.println(outMap);

Do Something like this

First Sort by Keys and after sort by values

    Map<String, Integer> map=new HashMap<String, Integer>();
     map.put("Login to new", 27);
     map.put("Failed login", 27);
     map.put("Impossible", 21);

     List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String, Integer>>(map.entrySet());

        //sort keys in ascending order
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
                return (e1.getKey()).compareTo(e2.getKey());
            }
        });

        //sort by values in descending order
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> e1, Map.Entry<String, Integer> e2) {
                return (e2.getValue()).compareTo(e1.getValue());
            }
        });


        Map<String, Integer> result = new LinkedHashMap<String, Integer>();
        for (Map.Entry<String, Integer> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }
        System.out.println(result);

Output

{Failed login=27, Login to new=27, Impossible=21}
public static void main(String...strings) throws IOException {
        Map<String, String[]> map = new TreeMap<String, String[]>(){            
            @Override
            public String[] put(String key, String[] value){
                Arrays.sort(value);
                return super.put(key, value);
            }
        };

        map.put("Apple11", new String[]{"Zinc", "Iridium", "Apple"});
        map.put("Apple1", new String[]{"Xenon", "Zinc", "Brass"});

        for (Entry<String, String[]> entry : map.entrySet()) {
            System.out.println(entry.getKey()+"  ::  "+Arrays.toString(entry.getValue()));
        }
    }

output ::

Apple1  ::  [Brass, Xenon, Zinc]
Apple11  ::  [Apple, Iridium, Zinc]

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