ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java8 Stream流

2021-07-21 14:31:15  阅读:192  来源: 互联网

标签:Stream stream list collect add Integer new Java8


目录


文中有使用到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 --结尾

标签:Stream,stream,list,collect,add,Integer,new,Java8
来源: https://blog.csdn.net/qq_41175917/article/details/118798379

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有