views:

25

answers:

1

I want to sort a hash of key->value by the values , and get the list of the sorted keys.

This seems to work:

groovy> def map = [a:5, b:3, c:6, d:4].sort { a, b -> a.value <=> b.value }.keySet() 
groovy> println map 

[b, d, a, c]

but will it always work? I don't know if the iterator that builds the keySet() will always iterate them by order.

Thanks!

+3  A: 

Short answer: Yes, the keySet() method will always return an ordered java.util.List.

Long answer: That's a bit hard to prove as we have to look at some source code.

Examination starts in groovy.runtime.DefaultGroovyMethods where the public static <K, V> Map<K, V> sort(Map<K, V> self, Closure closure) method returns a java.util.LinkedHashMap, which is ordered.

The LinkedHashMap's Set<K> keySet() method is defined in the java.util.HashMap class and returns an Iterator by calling the Iterator<K> newKeyIterator() method, which is overriden in the LinkedHashMap class][4]. It returns a LinkedHashMap$KeyIterator, which [defines the K next() method that internally calls the Entry<K,V> nextEntry() method, which returns an Entry that has been defined in the LinkedHashMap$Entry.after field.

Finally, one can see in the LinkedHashMap$Entry.addBefore(Entry<K,V> existingEntry) method that the LinkedHashMap$Entry.after field is set in an ordered manner.


Oh my ... I had linked each statement I did to the corresponding source code in groovy.runtime.DefaultGroovyMethods, java.util.HashMap and java.util.LinkedHashMap, summing up to 10 hyperlinks. Unfortunately, as a newbie at Stackoverflow, I'm just allowed to post one, having to remove most links ... Sorry.

robbbert
WOW , kudos man!
yossale