Java8新特性之:流(二)

三. 使用流java

    流的使用通常包括三件事:數組

        -- 一個數據源(如集合)來執行一個查詢;ide

        -- 一箇中間操做鏈,造成一條流的流水線;函數

        -- 一個終端操做,執行流水線,並能生成結果。spa

    1.流操做對象

        篩選、切片、映射、查找、匹配、概括。(快速完成複雜數據查詢)排序

    2.狀態接口

        無狀態操做:從輸入流中獲得0或1個結果。他們沒有內部狀態。如map、filter。ip

        有狀態操做:先接受一個流再生成一個流時,須要知道先前的歷史。get

    3.Optional<T>類(java.util.Optional)是一個容器類,表明一個值存在或不存在。

        Optional裏能夠迫使你顯式地檢查值是否存在或處理值不存在的情形的方法:

            -- isPresent()將在Optional包含值的時候返回true,不然返回false;

            -- ifPresent(Consumer<T> block)會在值存在的時候執行給定的代碼塊;

            -- T get()會在值存在時返回值,不然拋出一個NoSuchElement異常;

            -- T orElse(T other)會在值存在時返回值,不然返回一個默認值。

操做 描述 操做 類型 返回類型 使用的類型/函數式接口 函數描述符 說明

篩選

謂詞篩選 filter 中間 Stream<T> Predicate<T> T -> boolean
篩選各異元素 distinct() 中間(有狀態-×××) Stream<T>

確保沒有重複

切片

截短流 limit(n) 中間(有狀態-有界) Stream<T> long

跳過元素 skip(n) 中間(有狀態-有界) Stream<T> long
skip(n)與limit(n)互補

映射

對流中每個元素應用函數 map 中間 Stream<R> Function<T, R> T -> R 接受一個函數做爲參數
流的扁平化:各個數組並非分別映射成一個流,而是映射成留的內容 flatMap(Arrays::stream) 中間 Stream<R> Function<T, Stream<R>> T -> Stream<R> 將[h,e,l,l,o],[w,o,r,l,d]變成[h,e,l,l,o,w,o,r,l,d]

排序 sorted 中間(有狀態-×××) Stream<T> Comparator<T> (T, T) -> int

查找

返回當前流中的任意元素 findAny 終端 Optional<T>

//若是包含一個值就返回它,不然什麼都不作

menu.stream().filter(Dish::isvegetarian).findAny().ifPresent(d -> System.out.println(d.getName));

查找第一個元素 findFirst 終端 Optional<T>


匹配

檢查謂詞是否匹配至少一個元素 anyMatch 終端 boolean Predicate<T> T -> boolean

if(menu.stream().anyMatch(Dish::isVegetarian)) {

    System.out.println("The menu is (somewhat) vegetarian friendly!!");

}

檢查謂詞是否匹配全部元素 allMatch 終端 boolean Predicate<T> T -> boolean boolean isHealthy = menu.stream().allMatch(d -> d.getCalories() < 1000);
沒有任何元素與給定的謂詞匹配 noneMatch 終端 boolean Predicate<T> T -> boolean boolean isHealthy = menu.stream().noneMatch(d -> d.getCalories() >= 1000);

歸約

對流中的數字求和 reduce 終端(有狀態,有界) Optional<T> BinaryOperator<T> (T, T) -> T

//有初始值

int sum = numbers.stream().reduce(0, Integer :: sum);

//無初始值,返回Optional是考慮流中沒有任何元素的狀況,reduce元素沒法返回其和

Optional<Integer> sum = numbers.stream().reduce((a, b) -> a * b);

最大值 reduce(Integer::max) 終端(有狀態,有界) Optional<T>

Optional<Integer> max = numbers.stream().reduce(Integer::max);
最小值 reduce(Integer::min) 終端(有狀態,有界) Optional<T>

Optional<Integer> min = numbers.stream().reduce(Integer::min);

collect 終端 R Collector<T, A, R> T -> void


forEach 終端 void Consumer<T>


計算流中元素個數 count 終端 long

long count = menu.stream().count();

eg:

public void testList() {
    List<Integer> list1 = Arrays.asList(1,2,3);
    List<Integer> list2 = Arrays.asList(3,4);
    
    //給定列表[1,2,3],[3,4]返回[(1,3),(1,4),(2,3),(2,4),(3,3),(3,4)]
    List<int[]> result = list1.stream()
        .flatMap(i -> list2.stream().map(j -> new int[]{i, j})
        ).collect(Collectors.toList());
        
    //給定列表[1,2,3],[3,4]返回總和能被3整除的數對:(2,4)和(3,3)
    List<int[]> result1 = list1.stream()
            .flatMap(i -> list2.stream().filter(j -> (i + j) % 3 == 0)
            .map(j -> new int[]{i, j})
        )
        .collect(Collectors.toList());
}


    4.特殊的流

        數值流

        原始類型流特化:特化是爲了不裝箱形成的複雜性(相似int和Integer之間的效率差別)。

原始類型特化流接口 映射到數值流 將數值流轉換回對象流 Optional原始類型特化
IntStream mapToInt boxed() OptionalInt
DoubleStream mapToDouble boxed() OptionalDouble
LongStream mapToLong boxed() OptionalLong

        數值範圍:IntStream和LongStream有靜態方法幫助生成這種範圍:range(接受起始值)和rangeClosed(接受結束值)。


    5.構建流

建立流的方法 說明 舉例
Stream.of 經過顯式值建立流 Stream.of("hello", "world")
Stream.empty 獲得空流 Stream.empty()
Arrays.stream 由數組建立流

int[] numbers = {2,3,4,5};

int sum = Arrays.stream(numbers).sum();

Files.lines 由文件生成流,其中每一個元素都是給定文件中的一行

long uniqueWords = 0;

try(Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())){

uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" "))) //生成單詞流

.distinct().count;//刪除重複項並得出共有多少各不相同的單詞

} catch(IOException e) {}

Stream.iterate 由函數生成流:建立無限流,使用limit()方法限制流的大小

//依次對每一個新生成的值應用函數

Stream.iterate(0, n -> n + 2).limit(10).forEach(System.out::println);

Stream.generate

//接受一個Supplier<T>類型的Lambda提供新的值

IntStream tows = IntStream.generate(new IntSupplier() {

public int getAsInt() {

return 2;

}

});

相關文章
相關標籤/搜索