1. 程式人生 > >Java8-2-Lambda表達式實戰-一句話實現Map中按照Value排序

Java8-2-Lambda表達式實戰-一句話實現Map中按照Value排序

comparing java 但是 ortmap each 答案 new 代碼 ram

今天我們來實戰一把, 對Map的Value值排序進行簡化.

在以前的思路我們的做法如下:

/**

  • Map根據value排序;
  • @param map
  • @return
    */
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
    List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<K, V>>() {@Override
    br/>@Override
    return (o2.getValue()).compareTo(o1.getValue());
    }
    });
    Map<K, V> result = new LinkedHashMap<>();
    for (Map.Entry<K, V> entry : list) {
    result.put(entry.getKey(), entry.getValue());
    }
    return result;
    }
    什麽意思呢?意思就是先把Map變成可排序的List使用Comparator接口對entry進行排序, 可是這樣代碼很多很亂, 我們需要做一些簡化.

如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。

第一步: 使用Lambda表達式先對Comparator接口做簡化, 代碼會變成如下情況:

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());

list.sort(Comparator.comparing(Entry::getValue));
Map<K, V> result = new LinkedHashMap<>();

for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
這樣的話, 一行代碼就代替了五行, 但是會有個問題, 這樣寫只能從小到大排序很不靈活, 我們還有其他辦法.來看下面的代碼:

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());

list.sort((o1, o2)-> o2.getValue().compareTo(o1.getValue()));
Map<K, V> result = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
用lambda表達式就可以做到變換排序的方式, 只要改變o1和o2的順序就可以了.哎, 可以還是很長, 我還想再少幾句代碼, 怎麽辦?

我們來分析下最原始的排序代碼 ---> 首先是將Map轉化為List<Entry>利用List的可排序的特性排序後遍歷到新的Map裏面去, 這樣就很簡單了, 我們可以從遍歷的地方入手.代碼如下:

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());

list.sort((o1, o2)-> o2.getValue().compareTo(o1.getValue()));
Map<K, V> result = new LinkedHashMap<>();
list.stream().forEach(entry -> result.put(entry.getKey(), entry.getValue()));

return result;
}
也許做到上面這一步已經很滿足了, 可是作為一個優秀的開發人員怎麽能滿足於這種程度, 我們要用兩句話完成上面的功能.我們可以發現entrySet()是個集合, stream是有sort方法的, 可以set變成stream然後sort之後forEach到新的Map中, 牛逼吧, 廢話少說,看代碼.

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
Map<K, V> sortMap = new LinkedHashMap<>();
new map.entrySet().stream()
.sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue()))
.forEach(entry -> sortMap.put(entry.getKey(), entry.getValue()));
return sortMap;
}
高級程序員到這裏就可以了, 下面提供一個工具類給大家使用.

/**

  • flag = 1 正序
  • flag = 0 倒序
  • @param map
  • @param flag
  • @return
    */
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map, int flag) {
    Map<K, V> sortMap = new LinkedHashMap<>();
    if(flag == 1) {
    map.entrySet().stream()
    .sorted((o1, o2) -> o1.getValue().compareTo(o2.getValue()))
    .forEach(entry -> sortMap.put(entry.getKey(), entry.getValue()));
    } else {
    map.entrySet().stream()
    .sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue()))
    .forEach(entry -> sortMap.put(entry.getKey(), entry.getValue()));
    }
    return sortMap;
    }
    以上的代碼已經夠簡潔了, 但是有一個中間變量, 我作為一個究極程序員是看不慣的, 能不能把它也省略掉一句代碼實現整個功能呢? 答案是可以的.

如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java高級交流:854630135,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue2(Map<K, V> map, int flag) {

if(flag == 1) {
return map.entrySet().stream().sorted((o1, o2) -> o1.getValue().compareTo(o2.getValue())).map(entry -> {
Map<K, V> result = new LinkedHashMap<>();
result.put(entry.getKey(), entry.getValue());
return result;
}).reduce((map1, map2) -> {
map2.entrySet().forEach(entry -> map1.put(entry.getKey(), entry.getValue()));
return map1;
}).get();
} else {
return map.entrySet().stream().sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue())).map(entry -> {
Map<K, V> result = new LinkedHashMap<>();
result.put(entry.getKey(), entry.getValue());
return result;
}).reduce((map1, map2) -> {
map2.entrySet().forEach(entry -> map1.put(entry.getKey(), entry.getValue()));
return map1;
}).get();

}
思路是做好排序後將排序後的entry加入到新的Map裏面, 再將stream<Map<K,V>>進行疊加, 可能有些抽象, 不能明白的也只能幫到這啦.

Java8-2-Lambda表達式實戰-一句話實現Map中按照Value排序