JAVA 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());
}
}