0

I need to loop through a HashMap, but to give importance to the values' order. For example, consider the following hash map of <String, Integer>:

{"dog" : 2, "bird": 3, "cat" : 1}

Now, I need to loop through the hasp map in order of ascending values, so that

for () {
 System.out.println( currentKey );
}

will always output

"cat", "dog", "bird"

jmj
  • 237,923
  • 42
  • 401
  • 438
Joel
  • 5,949
  • 12
  • 42
  • 58
  • 2
    In your question, your keys and values both sort the same way, and so it's easy to misunderstand your question. If the map were `{"r" : 2, "q": 3, "z" : 1}`, would you want `z r q` (the order according to the values 1, 2, 3) or `q r z`? You've said "values' order" and so I *assume* you want `z r q` (the order according to the values 1, 2, 3), but... Also, can there be duplicate values? E.g., `{"r" : 2, "q": 3, "z" : 1, "w": 1}` (there are two entries with the value `1`). If so, what order do you want them in? By key? Indeterminate? – T.J. Crowder Jan 22 '11 at 10:18
  • You fixed the first part, not the second: *"Also, can there be duplicate values? E.g., `{"r" : 2, "q": 3, "z" : 1, "w": 1}` (there are two entries with the value `1`). If so, what order do you want them in? By key? Indeterminate?"* – T.J. Crowder Jan 22 '11 at 10:37

4 Answers4

4

Well, you may be interested in instead using a TreeMap, which sorts your entries by key.

Otherwise, you may be interested looking into Map.keySet(), Map.entrySet(), or Map.values().

If you still want to keep your Map a HashMap, you could use one of Collections' numerous functions for getting sorted collections (e.g. you could get a sorted version of your map, sort a list, etc).


Since I see you specifically want to sort by values, I think Michał Minicki's answer ought to be what you want.

Community
  • 1
  • 1
Zach L
  • 16,072
  • 4
  • 38
  • 39
4

Maybe this will help:

Sort a Map<Key, Value> by values (Java)

Community
  • 1
  • 1
Mike Minicki
  • 8,216
  • 11
  • 39
  • 43
1

If you want to have the map sort itself by value as you insert entries then the easiest way would probably be to use something like the TreeMultimap in Google's collections library.

If you still want to use a hashmap but have the values sorted when you retrieve them from the set, then you can take two approaches - either you can get the values using the values() method and then run Collections.sort() on the returned list, or you can again use a class like TreeMultimap, adding all the entries in the current hashmap and then enumerating through them.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Michael Berry
  • 70,193
  • 21
  • 157
  • 216
1

Another example using Guava:

Pros:

  • Returns entries (not just keys)
  • Does not require the keys to be Comparable

static <K, V>Set<Map.Entry<V, K>>
entriesByValue(Map<K, V> source, Comparator<V> cmp) {
    SortedMap<V, Collection<K>> inverseMap = Maps.newTreeMap(cmp);
    Supplier<Set<K>> setFactory = new Supplier<Set<K>>() {
        public Set<K> get() {
            return Sets.newHashSet();
        }
    };
    SetMultimap<V, K> inverseMM =
        Multimaps.newSetMultimap(inverseMap, setFactory);
    Multimaps.invertFrom(Multimaps.forMap(source), inverseMM);
    return Collections.unmodifiableSet(inverseMM.entries());
}
finnw
  • 47,861
  • 24
  • 143
  • 221