Oops Null Pointer

Java programming related

Monthly Archives: February 2011

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