Java基礎(chǔ)之Stream流(JDK1.8新特性)

定義

JDK1.8 中增加了Stream流,Stream流是一個(gè)來(lái)自數(shù)據(jù)源的元素隊(duì)列并支持聚合操作。
元素是特定類型的對(duì)象,形成一個(gè)隊(duì)列,Java中的Stream并不會(huì)存儲(chǔ)元素,而是按需計(jì)算
數(shù)據(jù)源是流的來(lái)源,可以使集合,數(shù)組,I/O channel,生成器generator等。
聚合操作類似SQL語(yǔ)句一樣的操作,比如filter,map,reduce,match,sorted等
操作的特征

1.中間的操作都會(huì)返回流對(duì)象本身,這樣多個(gè)操作可以串聯(lián)成一個(gè)管道,如同流式風(fēng)格
2.內(nèi)部迭代:以前對(duì)集合的遍歷是通過(guò)Iterator或者For-Each的方式,顯式的在集合外部進(jìn)行迭代,這叫做外部迭代,而Stream流式內(nèi)部迭代。
代碼示例
生成流

如下代碼的意思是,首先創(chuàng)建一個(gè)集合,然后過(guò)濾出所有不為空的元素,重新組成一個(gè)集合

 List<String> stringList = Arrays.asList("abc", "", "bc", "efg", "abcd", "");
        List<String> strings = stringList.stream().filter(string -> StringUtils.isNotBlank(string)).collect(Collectors.toList());
  System.out.println("*********過(guò)濾后的集合是"+strings);


forEach 迭代

        strings.forEach(System.out::println);

limit方法用于獲取指定數(shù)量的流

如下就是獲取一個(gè)長(zhǎng)度為10的流。

 Random random = new Random();
        random.ints().limit(10).forEach(System.out::println);

map

map方法用于映射每個(gè)元素,以下代碼片段使用map輸出元素對(duì)應(yīng)的平方數(shù)

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5, 8, 9);
        //獲取對(duì)應(yīng)的平方數(shù)
        List<Integer> integers = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
        System.out.println("*********獲取對(duì)應(yīng)的平方數(shù)"+integers);



sorted

sorted方法用于對(duì)流進(jìn)行排序
如下,就是按照元素的大小進(jìn)行排序

        List<Integer> orgList = Arrays.asList(10, 9, 8, 7, 6, 13, 16, 0, 1, 2);
        List<Integer> sortedList = orgList.stream().sorted().collect(Collectors.toList());
        System.out.println("*********排序后集合是"+sortedList);


并行(parallel)程序

 List<String> emptyList = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "");
        //獲取空字符串的數(shù)量
        long count = emptyList.parallelStream().filter(string -> string.isEmpty()).count();
        System.out.println("*****集合中的空字符串個(gè)數(shù)=" + count);



Collectors

Collectors類實(shí)現(xiàn)了很多歸約操作,例如將流轉(zhuǎn)換成集合和集合元素,Collectors可用于返回列表或字符串

 List<String> orgCollectors = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
        List<String> filtered = orgCollectors.stream().filter(string -> !string.isEmpty())
                .collect(Collectors.toList());
        System.out.println("篩選列表:" + filtered);

        String mergedString = stringList.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(","));
        System.out.println("合并字符串:" + mergedString);



統(tǒng)計(jì)

 //統(tǒng)計(jì)
            List<Integer> orgNums = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
            IntSummaryStatistics statistics = numbers.stream().mapToInt((x) -> x).summaryStatistics();
            System.out.println("列表中最大的數(shù):" + statistics.getMax());
            System.out.println("列表中最小的數(shù):" + statistics.getMin());
            System.out.println("所有數(shù)之和:" + statistics.getSum());
            System.out.println("平均數(shù):" + statistics.getAverage());



轉(zhuǎn)化(將枚舉類轉(zhuǎn)成map)

將一個(gè)枚舉類轉(zhuǎn)成一個(gè)map,使用的示例可以參考下方:

 Map<Integer, String> disableFlagMap = Arrays.stream(DisableFlagEnum.values()).collect(Collectors.toMap(p -> p.getCode(), p -> p.getDesc()));

  

完整的代碼是:

public enum DisableFlagEnum {
    NORMAL(0, "正常"),

    DELETE(1, "已刪除");

    private Integer code;

    private String desc;

    DisableFlagEnum(Integer code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public Integer getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }
	
    public static String getDesc(Integer code) {
        Map<Integer, String> disableFlagMap = Arrays.stream(DisableFlagEnum.values()).collect(Collectors.toMap(p -> p.getCode(), p -> p.getDesc()));
        return disableFlagMap.get(code);
    }
}

demo的運(yùn)行結(jié)果

總結(jié)

本文首先介紹了JDK1.8中的Stream流,Stream流是是一個(gè)來(lái)自數(shù)據(jù)源的元素隊(duì)列并支持聚合操作。它的特點(diǎn)就是中間過(guò)程不會(huì)存儲(chǔ)數(shù)據(jù),不會(huì)改變數(shù)據(jù)源本身。接著介紹了stream的使用示例,stream流的使用一般是要結(jié)合函數(shù)式接口使用的。
參考

Java 8 Stream





作者:碼農(nóng)飛哥
微信公眾號(hào):碼農(nóng)飛哥