恕我直言你可能真的不會java第12篇-如何使用Stream API對Map類型元素排序

在這篇文章中,您將學習如何使用Java對Map進行排序。前幾日有位朋友面試遇到了這個問題,看似很簡單的問題,可是若是不仔細研究一下也是很容易讓人懵圈的面試題。因此我決定寫這樣一篇文章。在Java中,有多種方法能夠對Map進行排序,可是咱們將重點介紹Java 8 Stream,這是實現目標的一種很是優雅的方法。vue

1、什麼是Java 8 Stream

使用Java 8 Streams,咱們能夠按鍵和按值對映射進行排序。下面是它的工做原理:java

Java Stream函數式編程?用過都說好,案例圖文詳解送給你

  1. 將Map或List等集合類對象轉換爲Stream對象
  2. 使用Streams的sorted()方法對其進行排序
  3. 最終將其返回爲LinkedHashMap(能夠保留排序順序)

sorted()方法以aComparator做爲參數,從而能夠按任何類型的值對Map進行排序。若是對Comparator不熟悉,能夠看本號前幾天的文章,有一篇文章專門介紹了使用Comparator對List進行排序。面試

2、學習一下HashMap的merge()函數

在學習Map排序以前,有必要講一下HashMap的merge()函數,該函數應用場景就是當Key重複的時候,如何處理Map的元素值。這個函數有三個參數:spring

  • 參數一:向map裏面put的鍵
  • 參數二:向map裏面put的值
  • 參數三:若是鍵發生重複,如何處理值。能夠是一個函數,也能夠寫成lambda表達式。
String k = "key";
        HashMap<String, Integer> map = new HashMap<String, Integer>() {{
            put(k, 1);
        }};
        map.merge(k, 2, (oldVal, newVal) -> oldVal + newVal);

看上面一段代碼,咱們首先建立了一個HashMap,並往裏面放入了一個鍵值爲k:1的元素。當咱們調用merge函數,往map裏面放入k:2鍵值對的時候,k鍵發生重複,就執行後面的lambda表達式。表達式的含義是:返回舊值oldVal加上新值newVal(1+2),如今map裏面只有一項元素那就是k:3。編程

其實lambda表達式很簡單:表示匿名函數,箭頭左側是參數,箭頭右側是函數體。函數的參數類型和返回值,由代碼上下文來肯定。

3、按Map的鍵排序

下面一個例子使用Java 8 Stream按Map的鍵進行排序:後端

// 建立一個Map,並填入數據
Map<String, Integer> codes = new HashMap<>();
codes.put("United States", 1);
codes.put("Germany", 49);
codes.put("France", 33);
codes.put("China", 86);
codes.put("Pakistan", 92);

// 按照Map的鍵進行排序
Map<String, Integer> sortedMap = codes.entrySet().stream()    
        .sorted(Map.Entry.comparingByKey())
        .collect(
                Collectors.toMap(
                    Map.Entry::getKey, 
                    Map.Entry::getValue,
                    (oldVal, newVal) -> oldVal,
                    LinkedHashMap::new
                )
        );

// 將排序後的Map打印
sortedMap.entrySet().forEach(System.out::println);

看上文中第二段代碼:springboot

  • 首先使用entrySet().stream() 將Map類型轉換爲Stream流類型。
  • 而後使用sorted方法排序,排序的依據是Map.Entry.comparingByKey(),也就是按照Map的鍵排序
  • 最後用collect方法將Stream流轉成LinkedHashMap。 其餘參數都好說,重點看第三個參數,就是一個merge規則的lambda表達式,與merge方法的第三個參數的用法一致。因爲本例中沒有重複的key,因此新值舊值隨便返回一個便可。

上面的程序將在控制檯上打印如下內容,鍵(國家/地區名稱)以天然字母順序排序:前後端分離

China=86
France=33
Germany=49
Pakistan=92
United States=1
請注意使用 LinkedHashMap來存儲排序的結果以保持順序。默認狀況下, Collectors.toMap()返回 HashMapHashMap不能保證元素的順序。

若是但願按照鍵進行逆向排序,加入下圖中紅色部分代碼便可。
函數式編程

4、按Map的值排序

固然,您也可使用Stream API按其值對Map進行排序:函數

Map<String, Integer> sortedMap2 = codes.entrySet().stream()
        .sorted(Map.Entry.comparingByValue())
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue,
                (oldVal, newVal) -> oldVal,
                LinkedHashMap::new));

sortedMap2.entrySet().forEach(System.out::println);

這是顯示Map按值排序的輸出:

United States=1
France=33
Germany=49
China=86
Pakistan=92

5、使用TreeMap按鍵排序

你們可能都知道TreeMap內的元素是有順序的,因此利用TreeMap排序也是可取的一種方法。您須要作的就是建立一個TreeMap對象,並將數據從HashMapput到TreeMap中,很是簡單:

// 將 `HashMap` 轉爲 `TreeMap`
Map<String, Integer> sorted = new TreeMap<>(codes);

這是輸出:

China=86
France=33
Germany=49
Pakistan=92
United States=1

如上所示,鍵(國家/地區名稱)以天然字母順序排序。

歡迎關注個人博客,裏面有不少精品合集

  • 本文轉載註明出處(必須帶鏈接,不能只轉文字):字母哥博客

以爲對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創做動力! 。另外,筆者最近一段時間輸出了以下的精品內容,期待您的關注。

相關文章
相關標籤/搜索