デフォルトの自然な順序ではなく、値によって TreeMap をソートできるコンパレータを作成したいと思います。
次のようなことを試してみましたが、何が悪かったのかわかりません。
import java.util.*;
class treeMap {
public static void main(String[] args) {
System.out.println("the main");
byValue cmp = new byValue();
Map<String, Integer> map = new TreeMap<String, Integer>(cmp);
map.put("de",10);
map.put("ab", 20);
map.put("a",5);
for (Map.Entry<String,Integer> pair: map.entrySet()) {
System.out.println(pair.getKey()+":"+pair.getValue());
}
}
}
class byValue implements Comparator<Map.Entry<String,Integer>> {
public int compare(Map.Entry<String,Integer> e1, Map.Entry<String,Integer> e2) {
if (e1.getValue() < e2.getValue()){
return 1;
} else if (e1.getValue() == e2.getValue()) {
return 0;
} else {
return -1;
}
}
}
私が尋ねているのは、Map.Entry
コンパレータに渡すことができるかどうかということです。
ベストアンサー1
TreeMap
それ自体を値でソートすることはできません。SortedMap
仕様:
さらに
Map
、トータルオーダーそのキー。
ただし、外部コレクションを使用すると、いつでも並べ替えることができますMap.entrySet()
キー、値、あるいはその 2 つの組み合わせ(!!) など、お望みどおりに使用できます。
以下は、値が である を与えられた場合に のSortedSet
を返す汎用メソッドです。Map.Entry
Map
Comparable
static <K,V extends Comparable<? super V>>
SortedSet<Map.Entry<K,V>> entriesSortedByValues(Map<K,V> map) {
SortedSet<Map.Entry<K,V>> sortedEntries = new TreeSet<Map.Entry<K,V>>(
new Comparator<Map.Entry<K,V>>() {
@Override public int compare(Map.Entry<K,V> e1, Map.Entry<K,V> e2) {
int res = e1.getValue().compareTo(e2.getValue());
return res != 0 ? res : 1;
}
}
);
sortedEntries.addAll(map.entrySet());
return sortedEntries;
}
これで、次の操作を実行できます。
Map<String,Integer> map = new TreeMap<String,Integer>();
map.put("A", 3);
map.put("B", 2);
map.put("C", 1);
System.out.println(map);
// prints "{A=3, B=2, C=1}"
System.out.println(entriesSortedByValues(map));
// prints "[C=1, B=2, A=3]"
SortedSet
自体、または内のを変更しようとするとMap.Entry
、これはもはや のような元のマップの「ビュー」ではないため、奇妙なことが起こることに注意してくださいentrySet()
。
一般的に言えば、マップのエントリをその値で並べ替える必要性はまれです。
注記==
Integer
元のコンパレータは をInteger
使用して比較します==
。これはほとんどの場合間違いです。オペランド==
はInteger
値の等価性ではなく参照の等価性であるためです。
System.out.println(new Integer(0) == new Integer(0)); // prints "false"!!!