Oops Null Pointer

Java programming related

Sort HashMap By value

Recently I evaluated a few methods of sorting a HashMap by value.

The two main ways I found (based on this thread were:

Using LinkedLists

  • Handles duplicate values by leaving keys in the same order they are in the source
  • This example passes in a comparator, but if the values are comparable you could use compareTo() instead
  • Performs a once off sort, so you need to re-sort if the map changes
public static <K, V> Map<K, V> sortByValue(Map<K, V> map, final Comparator<V> valueComparator)
    List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<K, V>>()  {
        public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
            return vComparator.compare(o1.getValue(), o2.getValue());
        }
    });

    Map<K, V> result = new LinkedHashMap<K, V>();
    for (Map.Entry<K, V> entry : list)  {
        result.put(entry.getKey(), entry.getValue());
    }
    return result;
} 

Using a TreeMap

  • Duplicates values will be removed from the tree so you need to add the key to the compare
  • In this example I use a comparator for both the values and the key (if the values are equal)
  • Always keeps the map sorted if the sorted map is used
Map baseMap = ...          
KeyComparator kComparator = new KeyComparator();
ValueComparator vComparator = new ValComparator();
          
MapValueComparator mapValComparator = new MapValueComparator(baseMap, kComparator, vComparator);
     
Map sortedMap = new TreeMap(mapValComparator);
sortedMap.putAll(baseMap);

The map value comparator use above:

public class MapValueComparator<K, V> implements Comparator<K>
{
    private Map<K,V> map;
    private Comparator<K> keyComparator;
    private Comparator<V> valueComparator;
    
    public MapValueComparator(Map<K, V> map, Comparator<K> keyComparator, Comparator<V> valueComparator) {
        this.map = map;
        this.valueComparator = valueComparator;
        this.keyComparator = keyComparator;
    }
    
    public int compare(K o1, K o2) {            
        int valueCompare = valueComparator.compare(map.get(o1), map.get(o2));
        if (valueCompare == 0) {
            return keyComparator.compare(o1, o2);
        }
        
        return valueCompare;
    }
}
Advertisements

One response to “Sort HashMap By value

  1. Ryan Clemson October 24, 2011 at 8:25 pm

    This needs to be added as default functionality in the JDK. Thanks for posting this. I would’ve never figured out the syntax:

    private Map sortByValue(….)

    Thanks again.

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

%d bloggers like this: