Как сортировать treemap на основе его значений?
Как я могу сортировать карту дерева, используя ее значения, а не ключ?
8 ответов
вы не можете, так как компаратор TreeMap работает только с ключами, например, см. Это конструктор.
в любом случае, вы можете использовать несколько коллекций, использовать TreeMap (или, скорее, HashMap) для поиска элементов по ключам и иметь SortedSet для итерации по значениям.
вот решение:
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;
}
обратите внимание, что карта сортируется от самого высокого значения до самого низкого.
Google Guava предоставляет TreeMultiMap.
вы также можете использовать две коллекции. Чего ты пытаешься добиться? Можете ли вы объяснить свои варианты использования?
Коллекции Apache Commons есть TreeBidiMap:
этот класс гарантирует, что карта будет в порядке возрастания клавиш и порядок возрастания значений, сортировка согласно естественному порядку для классы ключей и значений.
есть порт Java5-generics этого здесь.
попробуйте ниже кода, он отлично работает для меня. Для сортировки можно выбрать как восходящий, так и нисходящий порядок.
package com.rais;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class SortMapByValue
{
public static boolean ASC = true;
public static boolean DESC = false;
public static void main(String[] args)
{
// Creating dummy unsorted map
Map<String, Integer> unsortMap = new HashMap<String, Integer>();
unsortMap.put("B", 55);
unsortMap.put("A", 80);
unsortMap.put("D", 20);
unsortMap.put("C", 70);
System.out.println("Before sorting......");
printMap(unsortMap);
System.out.println("After sorting ascending order......");
Map<String, Integer> sortedMapAsc = sortByComparator(unsortMap, ASC);
printMap(sortedMapAsc);
System.out.println("After sorting descindeng order......");
Map<String, Integer> sortedMapDesc = sortByComparator(unsortMap, DESC);
printMap(sortedMapDesc);
}
private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap, final boolean order)
{
List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(unsortMap.entrySet());
// Sorting the list based on values
Collections.sort(list, new Comparator<Entry<String, Integer>>()
{
public int compare(Entry<String, Integer> o1,
Entry<String, Integer> o2)
{
if (order)
{
return o1.getValue().compareTo(o2.getValue());
}
else
{
return o2.getValue().compareTo(o1.getValue());
}
}
});
// Maintaining insertion order with the help of LinkedList
Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
for (Entry<String, Integer> entry : list)
{
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}
public static void printMap(Map<String, Integer> map)
{
for (Entry<String, Integer> entry : map.entrySet())
{
System.out.println("Key : " + entry.getKey() + " Value : "+ entry.getValue());
}
}
}
вы можете попробовать дать компаратор, который сравнивает значения вместо ключей при создании 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());
}
поменять местами значения и ключи.
более серьезно, пожалуйста, укажите некоторый контекст, чего вы хотите достичь. Может быть, достаточно отсортировать после завершения другой обработки.
Это я сделал это..
package Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
class MyComparator implements Comparator<Object> {
public int compare(Object o1, Object o2) {
return (((Integer) o2).compareTo((Integer) o1));
}
}
class MyComparator1 implements Comparator<Object> {
Map<Integer, String> map;
public MyComparator1(Map<Integer, String> m) {
this.map = m;
}
public int compare(Object o1, Object o2) {
return (((String) map.get(o1)).compareTo((String) map.get(o2)));
}
}
public class Map1 {
public static void main(String[] args) {
Map<Integer, String> hmap = new HashMap<Integer, String>();
hmap.put(5, "Ashok");
hmap.put(21, "Bhanu");
hmap.put(7, "chaman");
hmap.put(28, "dheeraj");
hmap.put(761, "edison");
hmap.put(1, "frank");
hmap.put(-6, "gopal");
hmap.put(78, "hari");
System.out.println("Hash Map:" + hmap);
Map<Integer, String> tmap = new TreeMap<>(hmap);
System.out.println("Tree Map:" + tmap);
MyComparator comp = new MyComparator();
Map<Integer, String> itmap = new TreeMap<>(comp);
itmap.putAll(hmap);
System.out.println("Tree Map Inreverse order:" + itmap);
Map<Integer, String> orderValuemap = new TreeMap<Integer, String>(new
MyComparator1(hmap));
orderValuemap.putAll(hmap);
orderValuemap.put(22,"hello");
for(Entry<Integer, String> mp:orderValuemap.entrySet())
System.out.println("Value : "+mp.getValue());
}
}