15
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("a", 4);
map.put("c", 6);
map.put("b", 2);

Desired output(HashMap):

c : 6
a : 4
b : 2

I haven't been able to find anything about Descending the order by value.
How can this be achieved? (Extra class not preferred)

Yjay
  • 2,717
  • 1
  • 18
  • 11
GameDevGuru
  • 1,095
  • 2
  • 12
  • 27
  • 1
    You can't. But you can sort the *Entries* (once in a List or other ordered collection) by value: to start, `List entries = new ArrayList>(hash.getEntries())`; then sort that. – user2864740 Jan 10 '14 at 21:09
  • @RC This is not the same question.. – GameDevGuru Jan 10 '14 at 21:13
  • 1
    (While I believe this is a "duplicate", the accepted answer in the other question is quite horrid - read over all the responses. I would also recommend using a [Array]List vs LinkedHashMap as the output collection.) – user2864740 Jan 10 '14 at 21:17
  • 1
    @GameDevGuru: Yes it is, except for trivial differences (map values being Strings instead of Integers). Read especially [this answer](http://stackoverflow.com/a/8119401/56285). You could also have a look at this question: http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java – Jonik Jan 10 '14 at 21:18
  • I want a million dollars. No, make that 10 million. – Hot Licks Jan 10 '14 at 21:18
  • @Jonik Can you just answer with something constructive instead of linking to posts with undesired results? Thanks – GameDevGuru Jan 10 '14 at 21:22
  • @user2864740 Thanks, I'm approaching the same idea. Code example would help greatly.. – GameDevGuru Jan 10 '14 at 21:23
  • @GameDevGuru If you wish the output is a List (e.g. for immediate use), see http://stackoverflow.com/a/13913206/2864740 and just skip the step in `sortByComparator` where it's puts the sorted data back into a *Map. I'd probably also use an ArrayList as the impl. through and through and the order conditional in the comparator can be removed. The types have to be updated a bit as well.. but the same concept should apply. – user2864740 Jan 10 '14 at 21:27
  • @Jonik Thank you for the for the only useful link throughout this whole post – GameDevGuru Jan 10 '14 at 21:47
  • what if the Integer == null? Does it come first or last? –  Jan 11 '14 at 03:05

3 Answers3

31

Try this:

HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 4);
map.put("c", 6);
map.put("b", 2);
Object[] a = map.entrySet().toArray();
Arrays.sort(a, new Comparator() {
    public int compare(Object o1, Object o2) {
        return ((Map.Entry<String, Integer>) o2).getValue()
                   .compareTo(((Map.Entry<String, Integer>) o1).getValue());
    }
});
for (Object e : a) {
    System.out.println(((Map.Entry<String, Integer>) e).getKey() + " : "
            + ((Map.Entry<String, Integer>) e).getValue());
}

output:

c : 6
a : 4
b : 2
NatNgs
  • 874
  • 14
  • 25
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
4

You can't explicity sort the HashMap, but can sort the entries. Maybe something like this helps:

// not yet sorted
List<Integer> intList = new ArrayList<Integer>(map.values());

Collections.sort(intList, new Comparator<Integer>() {

    public int compare(Integer o1, Integer o2) {
        // for descending order
        return o2 - o1;
    }
});
0

One of the characteristics of the Hash elements is their particular speed on doing operations like adding, deleting and so on, and this is precisely because they use Hash algorhythms, which means they doesn't keep the order of elements that we know as ascendant or descendant. That means that with the Hash data structures you won't achieve what you want.

nKn
  • 13,691
  • 9
  • 45
  • 62
  • 2
    It would be a very great suggestion to keep in mind however it does not answer the question. – Ashish Jan 10 '14 at 21:12
  • Instead of saying it's impossible, how about suggesting to cast it as an ArrayList first.. – GameDevGuru Jan 10 '14 at 21:14
  • @user2864740 List intList = new ArrayList(map); , and then working with the list. Or something to that effect. – GameDevGuru Jan 10 '14 at 21:18
  • @GameDevGuru But that's not a cast at all! For all casts in Java, where `x` is a reference type conforming to `T`: `((T)x) == x` is true. – user2864740 Jan 10 '14 at 21:20
  • @user2864740 I have used the wrong terminology, i apologize for the confusion but I think you know what i meant. – GameDevGuru Jan 10 '14 at 21:41