Sorting a HashMap by Value in Java vs Ruby

I’m working a graph problem in Java where I need to sort nodes by its edge count. I have a HashMap of nodes to edge count so I just need to sort a HashMap by its value.
A quick Google search brought up a few solutions. Below is a snippet of a typical solution from StackOverFlow


public static <k, V extends Comparable> List getKeysSortedByValue(Map map) {
    final int size = map.size();
    final List<map.Entry> list = new ArrayList<map.Entry>(size);
    list.addAll(map.entrySet());
    final ValueComparator cmp = new ValueComparator();
    Collections.sort(list, cmp);
    final List keys = new ArrayList(size);
    for (int i = 0; i < size; i++) {
        keys.set(i, list.get(i).getKey());
    }
    return keys;
}
private static final class ValueComparator<v extends Comparable>
                                     implements Comparator<map.Entry> {
    public int compare(Map.Entry o1, Map.Entry o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}

Can you believe it?? >10 lines of verbose madness! The Ruby solution is:

>> x = {:a => 1, :b => 2, :c => 1, :d => 5}
>> x.keys.sort_by{|k| x[k]}
=> [:a, :c, :b, :d]

This makes you really appreciate closure support in languages. Java 7′s support of closure should bring more sanity to the Java world.

I’m also learning Clojure right now, the solution is just as nice as Ruby.

user=> (def x {:a 1 :b 2 :c 1 :d 5})
user=> (sort-by #(x %) (keys x))
(:a :c :b :d)

edit:
In Scala, it is also very succinct:


scala> val x = Map('a' -> 1, 'b' -> 2, 'c' -> 1, 'd' -> 5)
x: scala.collection.immutable.Map[Char,Int] = Map((a,1), (b,2), (c,1), (d,5))
scala> x.keysIterator.toList.sortWith((key1,key2) => x(key1) < x(key2))
res5: List[Char] = List(a, c, b, d)

3 thoughts on “Sorting a HashMap by Value in Java vs Ruby

  1. Jim White

    Groovy is the coolest (i.e., most productive for Java programmers) way to do closures on the JVM. But your example doesn't even need a closure:[a:1, b:2, c:1, d:5].keySet().sort()==>[a, b, c, d]But say you wanted something other than the default order:[a:1, b:2, c:1, d:5].keySet().sort { – (it[0] as int) }==>[d, c, b, a]The dandy thing is those are real Java Collections (Collection, List, Set, Map), so that works with a gigantic base of existing Java libraries.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s