按key排序
- 自定义比较器comparator
- 使用构造器TreeMap(comparator)
import java.util.*;
public class SortMapByKey {
public static void main(String[] args) {
originalOrdinal(); // order by key asc
System.out.println();
customizeOrdinal(); // 自定义Key的排列逻辑,灵活性更高。
}
static void originalOrdinal() {
TreeMap<Integer, String> map = new TreeMap<>(); // 无参构造
map.put(3, "three");
map.put(1, "one");
map.put(6, "six");
map.put(7, "seven");
for (Map.Entry entry : map.entrySet()) {
System.out.println(entry);
}
}
static void customizeOrdinal() {
// 局部匿名类,有名对象descSeqRule。
Comparator<Integer> descSeqRule = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
int i1 = o1.intValue();
int i2 = o2.intValue();
if (i1 != i2) {
return (i1 > i2) ? -1 : 1;
} else {
return 0;
}
}
};
// 向TreeMap的构造方法中传入一个自定义的比较器。
// HashMap,LinkedHashMap,EnumMap类没有这样的构造器。所以只能用TreeMap。
TreeMap<Integer, String> map = new TreeMap<>(descSeqRule);
map.put(3, "three");
map.put(1, "one");
map.put(6, "six");
map.put(7, "seven");
for (Map.Entry entry : map.entrySet()) {
System.out.println(entry);
}
}
}
输出结果:
1=one
3=three
6=six
7=seven
7=seven
6=six
3=three
1=one
显而易见:如果Key的类型为自定义类型(如Person,Node, Info),则可以通过自定义比较器,并将该比较器传入TreeMap的构造方法。这样生成的TreeMap类对象就会按照我们想要的排序逻辑对put进的Entry进行排列。
按value排序
- 使用任意Map容器暂存所有要按照value的某种股则进行排序的Entry。
- 使用一种List容器,接收之前map中的所有entry。
- 自定义针对value的某种排列逻辑的比较器comparator。
- Collections.sort(list, comparator)
- 使用LinkedHashMap接收排序后的list中的元素。
import java.util.*;
public class SortMapByValue {
public static void main(String[] args) {
valueDescSeq();
}
static void valueDescSeq() {
Map<Character, Integer> map = new TreeMap<Character, Integer>();
map.put('t', 3);
map.put('o', 1);
map.put('s', 6);
map.put('e', 8);
Set<Map.Entry<Character, Integer>> entrySet = map.entrySet(); // 数据源
LinkedList<Map.Entry<Character, Integer>> list = new LinkedList<>(); // 目的地址
for (Map.Entry<Character, Integer> entry : entrySet) {
list.add(entry);
}
Comparator<Map.Entry<Character, Integer>> descValue = new Comparator<Map.Entry<Character, Integer>>() {
@Override
public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
int i1 = o1.getValue().intValue(); // 也可以不获取intValue。两个Integer也可以用>等比较符号进行比较。
int i2 = o2.getValue().intValue(); // 属于自动拆箱后的比较。而非运算符重载。
if (i1 != i2) {
return (i1 > i2) ? -1 : 1;
} else {
return 0;
}
}
};
Collections.sort(list, descValue); // JDK API
LinkedHashMap<Character, Integer> valueDescMap = new LinkedHashMap<Character, Integer>();
for (Map.Entry<Character, Integer> entry: list) {
valueDescMap.put(entry.getKey(), entry.getValue());
}
showMapByTraverseEntrySet(map);
System.out.println();
showMapByTraverseEntrySet(valueDescMap);
}
// 遍历map的两种方法,二选一。
private static <K, V> void showMapByTraverseEntrySet(Map<K, V> map) {
Set<Map.Entry<K, V>> entrySet = map.entrySet();
for (Map.Entry<K, V> entry : entrySet) {
System.out.println(entry);
}
}
private static <K, V> void showMapByTraverseKeySet(Map<K, V> map) {
Set<K> keySet = map.keySet();
for (K key : keySet) {
System.out.println(key + " = " + map.get(key));
}
}
}
输出结果:
e=8
o=1
s=6
t=3
e=8
s=6
t=3
o=1
依旧:map容器默认是按照key的XX(hashCode,还是说别的属性)进行排序。而此处key为Character类型,可以看出是按照ASCII码表顺序(数值增序)进行元素排列。
而如果我们的需求是按照value进行排序。则可以通过以上的方法进行操作。