一、Map简介
在讲解Map排序之前,我们先来稍微了解下map。map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等。其中这四者的区别如下(简单介绍):
1、HashMap:我们最常用的Map,它根据key的HashCode 值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的key值为Null(多条会覆盖);允许多条记录的Value为 Null。非同步的。
2、TreeMap: 能够把它保存的记录根据key排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。
3、Hashtable: 与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。
4、LinkedHashMap: 保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。
简单总结为:
map:无序
Treemap:默认是升序(以key作为标准)
Linkedhashmap:默认是插入数据时的顺序
二、Comparator接口
(A)、方法
int compare(T o1,T o2)
(B)、说明
比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
在前面的描述中,符号 sgn(expression) 表示 signum 数学函数,根据 expression 的值为负数、0 还是正数,该函数分别返回 -1、0 或 1。
简单来说就是,Comparator可以对集合对象或者数组进行排序的比较器接口,实现该接口的public compare(T o1,To2)方法即可实现排序,该方法主要是根据第一个参数o1,小于、等于或者大于o2分别返回负整数、0或者正整数。
(C)、参数:o1 - 要比较的第一个对象。
o2 - 要比较的第二个对象。
(D)、返回:根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
三、示例
1、按键排序
TreeMap<K,V>既可满足此类需求,向其构造方法 TreeMap(Comparator<? super K> comparator) 传入我们自定义的比较器即可实现按键排序。
/**
* 按Key进行排序
*/
@Test
public void TestSort1(){
Map<String, String> resultMap = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
});
resultMap.put("1", "kfc");
resultMap.put("2", "wnba");
resultMap.put("3", "nba");
resultMap.put("4", "cba");
for (Map.Entry<String, String> entry : resultMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
2、按值排序
Map本身按值排序是很有意义的,很多场合下都会遇到类似需求,可以认为其值是定义的某种规则或者权重。
原理:将待排序Map中的所有元素置于一个列表中,接着使用Collections的一个静态方法 sort(List<T> list, Comparator<? super T> c)
来排序列表,同样是用比较器定义比较规则。排序后的列表中的元素再依次装入Map,为了肯定的保证Map中元素与排序后的List中的元素的顺序一致,使用了LinkedHashMap数据类型。
/**
* 按Value进行排序
*/
@Test
public void TestSort2(){
Map<String, String> resultMap = new TreeMap<String, String>();
resultMap.put("kfc", "1");
resultMap.put("wnba", "2");
resultMap.put("nba", "6");
resultMap.put("cba", "4");
resultMap.put("eba", "5");
resultMap.put("ebe", "0");
Map<String, String> sortedMap = new LinkedHashMap<String, String>();
List<Map.Entry<String, String>> entryList = new ArrayList<Map.Entry<String, String>>(
resultMap.entrySet());
Collections.sort(entryList, new Comparator<Entry<String, String>>() {
@Override
public int compare(Entry<String, String> o1, Entry<String, String> o2) {
return o1.getValue().compareTo(o2.getValue());
}
});
Iterator<Map.Entry<String, String>> iter = entryList.iterator();
Map.Entry<String, String> tmpEntry = null;
while (iter.hasNext()) {
tmpEntry = iter.next();
sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
}
for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
3.随机排序
/**
* 三种排序
* 1.升序排列
* 2.降序排序
* 3.随机排序
*/
@Test
public void TestSort3() {
//默认的TreeMap升序排列
TreeMap<Integer, Integer> map1 = new TreeMap<Integer, Integer>();
//降序排序
TreeMap<Integer, Integer> map2 = new TreeMap<Integer, Integer>(new Comparator<Integer>() {
/*
* int compare(Object o1, Object o2) 返回一个基本类型的整型,
* 返回负数表示:o1 小于o2,
* 返回0 表示:o1和o2相等,
* 返回正数表示:o1大于o2。
*/
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
//随机排序
TreeMap<Integer, Integer> map3 = new TreeMap<Integer, Integer>(new Comparator<Integer>() {
/*
* int compare(Object o1, Object o2) 返回一个基本类型的整型,
* 返回负数表示:o1 小于o2,
* 返回0 表示:o1和o2相等,
* 返回正数表示:o1大于o2。
*/
public int compare(Integer a, Integer b) {
int randomOne = (int) (Math.random() * 10);
int randomTwo = (int) (Math.random() * 10);
return randomOne - randomTwo;
}
});
map2.put(1, 2);
map2.put(2, 4);
map2.put(2, 4);
map2.put(7, 1);
map2.put(5, 2);
System.out.println("Map2降序排列=" + map2);
map1.put(1, 2);
map1.put(2, 4);
map1.put(7, 1);
map1.put(5, 2);
map1.put(5, 2);
System.out.println("map1升序排序=" + map1);
map3.put(1, 2);
map3.put(2, 4);
map3.put(7, 1);
map3.put(5, 2);
map3.put(9, 2);
map3.put(11, 2);
map3.put(11, 2);
System.out.println("map3随机排序=" + map3);
}
4.Map转成List使用Collections.shuffle()随机排序
/**
* Map转List 随机排序
* @throws IOException
*/
@Test
public void TestSort4() throws IOException {
Map<String, Object> unsortMap = new HashMap<>();
unsortMap.put("z", 10);
unsortMap.put("b", 5);
unsortMap.put("a", 6);
unsortMap.put("c", 20);
unsortMap.put("d", 1);
unsortMap.put("e", 7);
unsortMap.put("y", 8);
unsortMap.put("n", 99);
unsortMap.put("g", 50);
unsortMap.put("m", 2);
unsortMap.put("f", 9);
List<String> list = new LinkedList(unsortMap.keySet());
//随机排序
Collections.shuffle(list);
Map<String,Object> result = new HashMap<String,Object>();
for (int i = 0; i < list.size(); i++) {
String jsonString = list.get(i);
result.put(jsonString, unsortMap.get(jsonString));
}
for (Map.Entry<String, Object> entry : result.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}