Java教程

Java8 Stream流

本文主要是介绍Java8 Stream流,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

    • Stream 的三个操作步骤
    • 创建Stream的几种方式
    • 中间操作
        • filter:排除
        • limit:截断
        • skip(n):跳过元素
        • distinct:去重
        • map:映射
        • sorted:排序
    • 终止操作
        • allMatch:检查是否匹配所有元素
        • anyMatch:检查是否至少匹配一个元素
        • noneMatch:检查是否没有匹配所有元素
        • findFirst:返回第一个元素
        • findAny:返回当前流中的任意元素
        • count:返回流中元素总个数
        • max:返回流中最大值
        • min:返回流中最大值
    • reduce:归约
    • collect:收集
        • 汇总
        • 计算
        • 分组
        • 多级分组
        • 分区
        • 字符串连接

文中有使用到Java8的Lambda表达式,若未学习,可点击下方链接学习Lambda表达式
链接: https://blog.csdn.net/qq_41175917/article/details/118785333.

Stream 的三个操作步骤

  • 1、创建 Stream
  • 2、中间操作
  • 3、终止操作(终端操作)

创建Stream的几种方式

  • 1、通过 Collection 系列集合提供的 stream() 或 parallelStream()
    	List<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();
    
  • 2、通过 Arrays 中的静态方法 stream() 获取数组流
        String[] strArr = new String[10];
        Stream<String> stream = Arrays.stream(strArr);
    
  • 3、通过 Stream 类中的静态方法 of()
        Stream<String> stream = Stream.of("aa", "bb", "cc");
    
  • 4、创建无限流,打印出来的结果为:从0开始,每一个元素比上一个大2,无限大下去
        Stream<Integer> integerStream = Stream.iterate(0, (x) -> x + 2);
    

中间操作

filter:排除

将list中小于等于20的值排除掉,最后遍历打印

      	// 排除掉小于等于20的元素
	    List<Integer> list = new ArrayList<Integer>(){{
            add(23);
            add(86);
            add(19);
        }};
        Stream<Integer> stream = list.stream()
                .filter((x) -> x > 20);
        stream.forEach(System.out::println);

输出:

23
86

limit:截断

获取并且打印数组的前两个数据

      	// 获取前两个元素
        List<Integer> list = new ArrayList<Integer>(){{
            add(23);
            add(86);
            add(19);
        }};
        list.stream()
                .limit(2)
                .forEach(System.out::println);

输出:

23
86

skip(n):跳过元素

跳过元素,返回一个冷掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与 limit(n) 互补。

      	// 跳过前两个元素
        new ArrayList<Integer>() {{
            add(23);
            add(86);
            add(19);
        }}.stream()
                .skip(2)
                .forEach(System.out::println);

输出:

19

distinct:去重

对 list 中的数据进行equals()对比去重。若 list 中存放的是对象,那么需要重写 hashCode() 和 equals() 方法,否则由于对象使用equals()对比得到的结果是false,会导致无法去重。

		// 去掉里面的重复项
        new ArrayList<Integer>() {{
            add(23);
            add(86);
            add(19);
            add(86);
            add(86);
        }}.stream()
                .distinct()
                .forEach(System.out::println);

输出:

23
86
19

map:映射

将元素转换成其他形式或提取信息。接受一个函数作为参数,该函数会应用到每个元素上,并将其映射成一个新到元素。

		// 将每个元素的值增加 100
        new ArrayList<Integer>() {{
            add(23);
            add(86);
            add(19);
        }}.stream()
                .map((i) -> i + 100)
                .forEach(System.out::println);

输出:

123
186
119

sorted:排序

        // 自然排序
        new ArrayList<Integer>() {{
            add(23);
            add(86);
            add(19);
        }}.stream()
                .sorted()
                .forEach(System.out::println);
                
        System.out.println("--------");
        
        // 定制排序,使用 lambda 表达式实现sorted方法参数中的Comparator中的接口,自定义排序方式
        new ArrayList<Integer>() {{
            add(23);
            add(86);
            add(19);
        }}.stream()
                .sorted((num1,num2) -> num2.compareTo(num1))
                .forEach(System.out::println);

输出:

19
23
86
--------
86
23
19

终止操作

allMatch:检查是否匹配所有元素

根据.allMatch 方法中的Lambda表达式,判断每个元素是否都满足条件,全部满足时返回true,有一个不满足则返回false

		// 判断list中每个数组元素下标为1的元素是否都等于3
		boolean allMatch = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }}.stream().allMatch((e) -> e[1] == 3);
        System.out.println(allMatch);

输出:

true

anyMatch:检查是否至少匹配一个元素

根据.anyMatch 方法中的Lambda表达式,判断是否至少有一个元素满足条件,至少一个满足时返回true,全都不满足则返回false

		// 判断list中是否至少有一个数组元素下标为2的元素等于4
        boolean anyMatch = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }}.stream().anyMatch((e) -> e[2] == 4);
        System.out.println(anyMatch);

输出:

true

noneMatch:检查是否没有匹配所有元素

根据.noneMatch 方法中的Lambda表达式,判断是否所有元素都不满足条件,都不满足时方式true,只要至少有一个元素满足了,就返回false

		// 判断list中是否所有数组元素下标为2的元素都不等于7
        boolean noneMatch = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }}.stream().noneMatch((e) -> e[2] == 7);
        System.out.println(noneMatch);

输出:

true

findFirst:返回第一个元素

获取流中第一个元素,我们可以在前面加排序什么的,得到排序后的第一个,然后使用get()方法取出元素进行后续操作。

		// 获取第一个数组元素中下标为1的值
        Optional<Integer[]> optional = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }}.stream().findFirst();
        // 如果optional的值 为空,那么可以设置替代值,当然需不需要看你需求
        optional.orElse(new Integer[]{0,0,0});
        System.out.println(optional.get()[1]);

输出:

3

findAny:返回当前流中的任意元素

        Optional<Integer[]> optional = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }}.stream().findAny();
        // 如果optional的值 为空,那么可以设置替代值,当然需不需要看你需求
        optional.orElse(new Integer[]{0,0,0});
        System.out.println(optional.get()[2]);

输出:

4

count:返回流中元素总个数

        long count = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }}.stream().count();
        System.out.println(count);

max:返回流中最大值

根据.max 方法中的Lambda表达式,自定义计算方式排序,得到你认为最大的元素。

		// 获取所有数组元素中,数组2下标最大的数组,并且打印该数组下标2的元素
        Optional<Integer[]> max = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }}.stream().max((a1, a2) -> a1[2].compareTo(a2[2]));
        System.out.println(max.get()[2]);

输出:

6

min:返回流中最大值

根据.max 方法中的Lambda表达式,自定义计算方式排序,得到你最小的元素。

		// 获取所有数组元素中,数组2下标最大的数组,并且打印该数组下标2的元素
        Optional<Integer[]> min = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }}.stream().min((a1, a2) -> a1[2].compareTo(a2[2]));
        System.out.println(min.get()[2]);

输出:

3

reduce:归约

可以将流中元素反复结合起来,得到一个值

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 将100作为基数,将list中的所有元素往100上累加,每加上一个元素,就把加后的值当作x,后一个元素当作y,再往后加
        Integer reduce = list.stream()
                .reduce(100, (x, y) -> x + y);
        System.out.println(reduce);
        // 没有基数,直接累加,但是因为没有起始值,所以结果可能为空,所以使用Optional接收值
        Optional<Integer> reduce1 = list.stream()
                .reduce(Integer::sum);
        System.out.println(reduce1.get());

输出:

155
55

collect:收集

将流转换为其他形式。接收一个Collector接口的实现,用户给Stream中元素做汇总的方法。

汇总

		// 把list中每个数组元素的第3个元素取出来,放到一个新的list中
        ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }};
        List<Integer> collect = list
                .stream()
                .map((a) -> a[2])
                .collect(Collectors.toList());
        collect
                .stream()
                .forEach(System.out::println);

输出:

4
6
3

若我们需要放到特殊的容器中,比如HashSet

		.collect(Collectors.toCollection(HashSet::new));

计算

        ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 3, 3});
        }};
        // 获取总数 结果 3
        Long collect = list.stream().collect(Collectors.counting());
        // 平均值(每个数组元素的第三个值,取出来算平均值) 结果 4.33333
        Double collect1 = list.stream().collect(Collectors.averagingInt((a) -> a[2]));
        // 求和(每个数组元素的第三个值,取出来求和) 结果 13.0
        Double collect2 = list.stream().collect(Collectors.summingDouble((a) -> a[2]));
        // 获取每个元素下标为2的最大值 结果 6
        Optional<Integer> collect3 = list.stream().map((x)->x[2]).collect(Collectors.maxBy((a1, a2) -> a1.compareTo(a2)));
        // 获取每个元素下标为2的最小值 结果 3
        Optional<Integer> collect4 = list.stream().map((x)->x[2]).collect(Collectors.minBy(Integer::compareTo));
        // 总函数
        DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble((e) -> e[2]));
        System.out.println("求和:" + collect.getSum());
        System.out.println("平均值:" + collect.getAverage());
        System.out.println("最大值:" + collect.getMax());

分组

        // 按照每个数组的第二个元素进行分组
        ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{8, 4, 3});
        }};
        Map<Integer, List<Integer[]>> collect = list.stream().collect(Collectors.groupingBy((e) -> e[1]));
        System.out.println(new Gson().toJson(collect));

输出:

{"3":[[2,3,4],[1,3,6]],"4":[[8,4,3]]}

多级分组

		// 先按照每个数组多第二个元素进行分组,然后每个分组里,按照第一个元素进行分组
        ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{1, 3, 7});
            add(new Integer[]{8, 4, 3});
        }};
        Map<Object, Map<Object, List<Integer[]>>> collect = list.stream()
                .collect(Collectors.groupingBy((e) -> e[1]
                        ,Collectors.groupingBy((q) -> q[0])
                ));
        System.out.println(new Gson().toJson(collect));

输出:

{"3":{"1":[[1,3,6],[1,3,7]],"2":[[2,3,4]]},"4":{"8":[[8,4,3]]}}

分区

		// 每个数组的第一个元素为1的分到true这一区,不为1的分false区
        ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
            add(new Integer[]{2, 3, 4});
            add(new Integer[]{1, 3, 6});
            add(new Integer[]{1, 3, 7});
            add(new Integer[]{8, 4, 3});
        }};
        Map<Boolean, List<Integer[]>> collect = list.stream().collect(Collectors.partitioningBy((e) -> e[0] == 1));
        System.out.println(new Gson().toJson(collect));

输出:

{"false":[[2,3,4],[8,4,3]],"true":[[1,3,6],[1,3,7]]}

字符串连接

		// 讲每个数组的第3个元素取出来拼接在一起
        ArrayList<String[]> list = new ArrayList<String[]>() {{
            add(new String[]{"2", "3", "4"});
            add(new String[]{"1", "5", "6"});
        }};
        String collect = list.stream()
                .map((e) -> e[2])
                .collect(Collectors.joining());
        System.out.println(collect);
        
        collect = list.stream()
                .map((e) -> e[2])
                .collect(Collectors.joining(","));
        System.out.println(collect);

        collect = list.stream()
                .map((e) -> e[2])
                .collect(Collectors.joining(",","前缀-- "," --结尾"));
        System.out.println(collect);

输出:

46
4,6
前缀-- 4,6 --结尾
这篇关于Java8 Stream流的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!