language: Java (sun-jdk-1.7.0_10)
date: 539 days 5 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
 
import java.lang.*;
import java.util.*;
 
public class Main {
 
 
 
    public static void main(String[] args) {
 
        // If you want to sort a map by value, and if there can be twice the same value:
 
        // here is your original map
        Map<String,Integer> mapToSortByValue = new HashMap<String, Integer>();
        mapToSortByValue.put("A", 3);
        mapToSortByValue.put("B", 1);
        mapToSortByValue.put("C", 3);
        mapToSortByValue.put("D", 5);
        mapToSortByValue.put("E", -1);
        mapToSortByValue.put("F", 1000);
        mapToSortByValue.put("G", 79);
        mapToSortByValue.put("H", 15);
        
        // Sort all the map entries by value
        Set<Map.Entry<String,Integer>> set = new TreeSet<Map.Entry<String,Integer>>(
                new Comparator<Map.Entry<String,Integer>>(){
                    @Override
                    public int compare(Map.Entry<String,Integer> obj1, Map.Entry<String,Integer> obj2) {
                        Integer val1 = obj1.getValue();
                        Integer val2 = obj2.getValue();
                        // DUPLICATE VALUE CASE
                        // If the values are equals, we can't return 0 because the 2 entries would be considered
                        // as equals and one of them would be deleted (because we use a set, no duplicate, remember!)
                        int compareValues = val1.compareTo(val2);
                        if ( compareValues == 0 ) {
                            String key1 = obj1.getKey();
                            String key2 = obj2.getKey();
                            int compareKeys = key1.compareTo(key2);
                            if ( compareKeys == 0 ) {
                                // what you return here will tell us if you keep REAL KEY-VALUE duplicates in your set
                                // if you want to, do whatever you want but do not return 0 (but don't break the comparator contract!)
                                return 0;
                            }
                            return compareKeys;
                        }
                        return compareValues;
                    }
                }
        );
        set.addAll(mapToSortByValue.entrySet());
 
 
        // OK NOW OUR SET IS SORTED COOL!!!!
 
        // And there's nothing more to do: the entries are sorted by value!
        for ( Map.Entry<String,Integer> entry : set ) {
            System.out.println("Set entries: " + entry.getKey() + " -> " + entry.getValue());
        }
 
 
        
 
        // But if you add them to an hashmap
        Map<String,Integer> myMap = new HashMap<String,Integer>();
        // When iterating over the set the order is still good in the println...
        for ( Map.Entry<String,Integer> entry : set ) {
            System.out.println("Added to result map entries: " + entry.getKey() + " " + entry.getValue());
            myMap.put(entry.getKey(), entry.getValue());
        }
 
        // But once they are in the hashmap, the order is not kept!
        for ( Integer value : myMap.values() ) {
            System.out.println("Result map values: " + value);
        }
        // Also this way doesn't work:
        // Logic because the entryset is a hashset for hashmaps and not a treeset
        // (and even if it was a treeset, it would be on the keys only)
        for ( Map.Entry<String,Integer> entry : myMap.entrySet() ) {
            System.out.println("Result map entries: " + entry.getKey() + " -> " + entry.getValue());
        }
 
 
        // CONCLUSION:
        // If you want to iterate on a map ordered by value, you need to remember:
        // 1) Maps are only sorted by keys, so you can't sort them directly by value
        // 2) So you simply CAN'T return a map to a sortMapByValue function
        // 3) You can't reverse the keys and the values because you have duplicate values
        //    This also means you can't neither use Guava/Commons bidirectionnal treemaps or stuff like that
 
        // SOLUTIONS
        // So you can:
        // 1) only sort the values which is easy, but you loose the key/value link (since you have duplicate values)
        // 2) sort the map entries, but don't forget to handle the duplicate value case (like i did)
    }
 
}
  • upload with new input
  • result: Success     time: 0.1s    memory: 213760 kB     returned value: 0

    Set entries: E -> -1
    Set entries: B -> 1
    Set entries: A -> 3
    Set entries: C -> 3
    Set entries: D -> 5
    Set entries: H -> 15
    Set entries: G -> 79
    Set entries: F -> 1000
    Added to result map entries: E -1
    Added to result map entries: B 1
    Added to result map entries: A 3
    Added to result map entries: C 3
    Added to result map entries: D 5
    Added to result map entries: H 15
    Added to result map entries: G 79
    Added to result map entries: F 1000
    Result map values: 5
    Result map values: -1
    Result map values: 1000
    Result map values: 79
    Result map values: 3
    Result map values: 1
    Result map values: 3
    Result map values: 15
    Result map entries: D -> 5
    Result map entries: E -> -1
    Result map entries: F -> 1000
    Result map entries: G -> 79
    Result map entries: A -> 3
    Result map entries: B -> 1
    Result map entries: C -> 3
    Result map entries: H -> 15