tags:

views:

1465

answers:

7

How can I sort a treemap using its values rather than the key?

A: 

Swap values and keys.

More seriously, please provide some context what you want to achieve. Maybe it is enough to sort after other processing is finished.

starblue
how can i swap them?
Click Upvote
He means you should use whatever you're using as key now as the value, and vice versa. That way you can sort on your value, which is now the key.
Jorn
This is generally a poor approach since the map has unique keys (with respect to compareTo) but not necessarily unique values. Create a new map with keys swapped with values might give you a different data set.
Buhb
A: 

You could try giving a Comparator that compare values instead of keys when you create the TreeMap.

 final TreeMap<Integer,String> tree = new TreeMap<Integer,String>();
 tree.put(1, "1");
 tree.put(2, "2");
 tree.put(3, "3");
 tree.put(4, "4");

 final TreeMap<Integer,String> treeSortedByValues = new TreeMap<Integer,String>(new Comparator<Integer>()
 {
  public int compare(Integer o1, Integer o2)
  {
   return tree.get(o1).compareTo(tree.get(o2));
  }
 });
 treeSortedByValues.putAll(tree);

 for ( Entry<Integer, String> e : treeSortedByValues.entrySet() )
 {
  System.out.println(e.getKey() + ": " + e.getValue());
 }
Vincent Robert
How will the comparator get access to the values ?
Zed
It won't. This isn't possible with the TreeMap.
Jorn
True, you cannot access the treemap values in the comparator since the treemap is not created yet. But you can use a temporary treemap for that...
Vincent Robert
+1  A: 

Apache Commons Collections has a TreeBidiMap:

This class guarantees that the map will be in both ascending key order and ascending value order, sorted according to the natural order for the key's and value's classes.

There's a Java5-generics port of it here.

skaffman
+1  A: 

You cannot as the TreeMap's comparator is run against the keys only, e.g. see this constructor.

Anyway, you can use multiple Collections, use the TreeMap (or rather HashMap) for looking up elements by keys, and have a SortedSet to iterate on the values.

Zed
A: 

Few weeks ago I also had this question and this link help me a lot:

http://paaloliver.wordpress.com/2006/01/24/sorting-maps-in-java/

Hope it helps you too.:)

DarkFire21
+2  A: 

Google Collections provides a TreeMultiMap.

You could also use two collections. What are you trying to accomplish? Can you explain your use cases?

richs
A: 

Here is a solution:

public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
Comparator<K> valueComparator =  new Comparator<K>() {
    public int compare(K k1, K k2) {
        int compare = map.get(k2).compareTo(map.get(k1));
        if (compare == 0) return 1;
        else return compare;
    }
};
Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
sortedByValues.putAll(map);
return sortedByValues;

}

Note that the map is sorted from the highest value to the lowest.

Anthony