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)

About tommychheng
I write a tech blog at http://tommy.chheng.com

3 Responses to Sorting a HashMap by Value in Java vs Ruby

  1. #(x %) is here equivalent to x, so it’s better to write (sort-by x (keys x))

  2. Jim White says:

    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.

  3. rjeka hotels says:

    where do i get more information on thisHavenspire, bring value and joy. …,

Leave a Reply

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

Gravatar
WordPress.com Logo

Please log in to WordPress.com to post a comment to your blog.

Twitter picture

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

Facebook photo

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

Connecting to %s

Follow

Get every new post delivered to your Inbox.