天天看點

Java中的流式程式設計(Stream)

1 Stream介紹

Stream是Java 8 的新功能,是對集合(Collection)對象功能的增強,可以非常友善地對集合中的對象進行操作。
	與Lambda表達式結合,可以提高程式設計效率、代碼的簡潔性與可讀性。Stream流其實是一個集合元素的函數模型,
	它并不是集合,也不是資料結構,其實本身并不存儲任何元素Stream是一個來自資料源的元素隊列。
	注意:Stream就如同一個疊代器,單向不可往複。
           

2 Stream方法

2.1 過濾

  • peek():幫助調試,允許無修改地檢視流中的元素。
  • sorted():排序,可以傳入Comparator參數。
  • disrinct():消除流中的重複元素。
  • filter(Predicate):過濾操作則會留下使用過濾方法傳回值為true的元素。

2.2 應用函數到元素

  • map(Function):将原來流中的每個元素都調用參數裡的方法,其傳回值彙總起來産生一個新的流。
  • mapToInt(ToIntFunction):結果為IntStream。
  • mapToLong(ToLongFunction):結果為LongStream。
  • mapToDouble(ToDoubleFunction):結果為DoubleStream。

2.3 結束操作

  • toArray():将流轉換成适當類型的數組。
  • toArray(generator):在特殊情況下,生成器用于配置設定自定義的數組存儲。
  • forEach(Consumer): 如使用System.out::println 作為函數。
  • forEachOrdered(Consumer):確定按照流的順序執行。
  • parallel():可實作多處理器并行操作。實作原理是将流分割為多個(通常數目為 CPU 核心數)并在不同處理器上分别執行操作。而進行并行操作的時候,forEach操作無法保證元素按原來的順序輸出,而forEachOrdered則可以確定按原來的順序輸出。

2.4 收集流元素到集合

  • collection(Collector):使用Collector收集流元素到集合中。
  • collect(Sipplier,BiConsumer,BiConsumer):收集流元素到結果集合中,第一個參數用于建立新的結果集合,第二個參數用于将下一個元素加入到現有結果集合中,第三個參數用于将兩個結果合集合并。

2.5 比對

  • allMatch(Predicate) :如果流的每個元素根據提供的 Predicate 都傳回 true 時,最終結果傳回為 true。這個操作将會在第一個 false 之後短路,也就是不會在發生 false 之後繼續執行計算。
  • anyMatch(Predicate):如果流中的任意一個元素根據提供的 Predicate 傳回 true 時,最終結果傳回為 true。這個操作将會在第一個 true 之後短路,也就是不會在發生 true 之後繼續執行計算。
  • noneMatch(Predicate):如果流的每個元素根據提供的 Predicate 都傳回 false 時,最終結果傳回為 true。這個操作将會在第一個 true 之後短路,也就是不會在發生 true 之後繼續執行計算。

2.6 查找元素

  • findFirst():傳回一個含有第一個流元素的 Optional類型的對象,如果流為空傳回 Optional.empty。
  • findAny():傳回含有任意流元素的 Optional類型的對象,如果流為空傳回 Optional.empty。

2.7 統計

  • average():求取流元素平均值
  • max() 和 min():求元素的最大值和最小值,對于非數字流則要多一個Comparator參數。
  • sum():對所有流元素進行求和。
  • count():流中的元素個數。

3 示例

public Map<Long, List<WorkSite>> testCase(List<Long> workSiteChoie) {
        WorkSite workSite11 = new WorkSite(3L, "測試地點1", 120.32, 30.24,1.1);
        WorkSite workSite12 = new WorkSite(3L, "測試地點2", 120.54, 31.44,2.0);
        WorkSite workSite13 = new WorkSite(3L, "測試地點3", 121.42, 37.22,3.0);
        WorkSite workSite21 = new WorkSite(2L, "測試地點4", 124.76, 31.10,4.0);
        WorkSite workSite22 = new WorkSite(2L, "測試地點5", 130.17, 30.55,5.0);
        WorkSite workSite23 = new WorkSite(2L, "測試地點6", 130.17, 30.55,6.0);
        WorkSite workSite31 = new WorkSite(1L, "測試地點7", 130.17, 30.55,7.0);
        WorkSite workSite32 = new WorkSite(1L, "測試地點8", 130.17, 30.55,8.0);
        WorkSite workSite33 = new WorkSite(1L, "測試地點9", 130.17, 30.55,9.0);
        List<WorkSite> workSites = Arrays.asList(workSite11, workSite12, workSite13, workSite21, workSite22,workSite23,
            workSite31,workSite32,workSite33);
    	
        List<WorkSite> workSiteList = workSites.stream()
            // 過濾掉ID為空的資料
            .filter(workSite -> workSite.getId() != null)
            // 去重
            .distinct()
            // 選擇資料處理
            .peek(workSite -> {
                    if (workSiteIds != null && workSiteIds.contains(workSite.getId())){
                        workSite.setChoose(true);
                    }
                })
            // 根據距離排序
            .sorted(Comparator.comparing(WorkSite::getDistance))
            .collect(Collectors.toList());
    	
        Map<Long, List<WorkSite>> collect = workSiteList.stream()
            // 根據id分組
            .collect(Collectors.groupingBy(WorkSite::getId));
        collect.forEach((k,v)-> {
                System.out.println("key : " + k + " value : " + v);
            });
    	reture collect;
    }