【jdk1.8特性】之Stream(上)

本文深入讲解Java Stream API的使用,涵盖串行流与并行流的获取方法、常见操作如filter、map、reduce等,以及排序、去重、归并等高级应用。通过示例代码演示如何高效利用Stream处理集合数据。

笔者日常 Stream知识点真的是…太多了!!!


声明 由于Stream知识极多,所以本人将其分为两个部分进行学习。

Stream(上)主要学习的内容有:
本文所学习的知识
Stream(下)主要学习的内容有:
在这里插入图片描述


Stream学习(上)

  • Stream实例的(常用)获取方法

    • 串行流:
      • Collection.stream()
      • Stream.of(T… values)
      • stream.sequential()
      • Arrays.stream()
      • ……
    • 并行流:
      • Collection.parallelStream()
      • stream.parallel()
    • 相关说明:
      • 串行流由单线程进行处理执行, 并行流由多线程进行处理执行。
      • 在多核的情况下,并行流效率更高。
      • 推荐使用Stream,而不使用显示迭代(如: for循环等)。
      • 显示循环、串行流、并行流的性能比较可参考here
      • 串行流、并行流的只是介绍可参考here
      • 在使用并行流时,如果只是用其来处理集合A本身的话,是不会有线程问题的(其内部会自己处理好);如果在使用并行流的时候,涉及到了其他变量B,那么可能出现线程不安全的情况。 如:listA.parallelStream().map(x -> {listB.add(x); return x;}).forEachOrdered(System.out::print)中,listA的并行流中 进行x -> {listB.add(x); return x;}操作,即:多线程中调用listB的add方法,如果listB是线程不安全的,那么就可能出现问题。
    • 示例:
      	/**
          * 获取串行流:
          *     Collection.stream(): 获取串行Stream
          *     Stream.of(T... values): 获取串行Stream
          *     stream.sequential(): 获取串行Stream
          *     Arrays.stream()
          *     ……
          *
          * 获取并行流:
          *     Collection.parallelStream(): 获取并行Stream
          *     stream.parallel(): 获取并行Stream
          *     ……
          *
          * 注:获取Stream实例的方式方式比较多,这里只示例了最基本的几种方式。
          *
          * 相关说明:
          *    1、串行流由单线程进行处理执行, 并行流由多线程进行处理执行。
          *    2、在多核的情况下,并行流效率更高。
          *    3、推荐使用Stream,而不使用显示迭代(如: for循环等)。
          *    4、显示循环、串行流、并行流的性能比较可参考<linked>https://blog.csdn.net/java1856905/article/details/88640557</linked>
          *    5、串行流、并行流的只是介绍可参考<linked>https://www.jianshu.com/p/19ffb2c9438a</linked>
          *    6、在使用并行流时,如果只是用其来处理集合A本身的话,是不会有线程问题的(其内部会自己处理好);如果在使用并
          *       行流的时候,涉及到了其他变量B,那么可能出现线程不安全的情况。 如:
          *       listA.parallelStream()
          *       .map(x -> {listB.add(x); return x;})
          *       .forEachOrdered(x -> System.out.print(x)
          *       中,listA的并行流中 进行x -> {listB.add(x); return x;}操作,
          *       即: 多线程中调用listB的add方法,如果listB是线程不安全的,那么就可能出现问题。
          */
         @Test
         public void test1() {
             
             
             // 数据准备
             List<Staff> tmpList = Lists.newArrayList(
                     Staff.builder().name("张三").age(18).staffNo("NO1").build(),
                     Staff.builder().name("李四").age(25).staffNo("NO2").build(),
                     Staff.builder().name("王五").age(40).staffNo("NO3").build()
             );
         
             /// 获取串行Stream
             // 常用方式一
             Stream<Staff> stream = tmpList.stream();
             // 常用方式二
             // 这样:
             // Stream<Staff> stream = Stream.of(a, b, c);
             // 或这样:
             // Staff[] tmpArray = {a, b, c};
             // Stream<Staff> stream = Stream.of(tmpArray);
             // 或这样:
             // Arrays.stream()
         
             /// 获取并行Stream
             // Stream<Staff> stream = tmpList.parallelStream();
             // Stream.of(a, b, c).parallel();
         }
      
  • boolean allMatch(Predicate<? super T> predicate) 是否【所有元素都满足Predicate】。

  • boolean allMatch(Predicate<? super T> predicate) 是否【存在元素满足Predicate】。

  • boolean noneMatch(Predicate<? super T> predicate) 是否【所有元素都不满足Predicate】。

    • 示例:
      /**
       * boolean allMatch: 是否【所有元素都满足Predicate】
       * boolean anyMatch: 是否【存在元素满足Predicate】
       * boolean noneMatch: 是否【所有元素都不满足Predicate】
       */
      @Test
      public void test2() {
             
             
          // 数据准备
          List<Staff> tmpList = Lists.newArrayList(
                  Staff.builder().name("张三").age(18).staffNo("NO1").build(),
                  Staff.builder().name("李四").age(25).staffNo("NO2").build(),
                  Staff.builder().name("王五").age(40).staffNo("NO3").build()
          );
          Stream<Staff> stream = tmpList.stream();
      
          // -> Stream.allMatch 测试
          // Predicate<Staff> predicateOne = x -> x.getAge() >= 18;
          // 控制台输出true。 即:stream中的所有Staff均满足predicateOne.
          // System.out.println(stream.allMatch(predicateOne));
      
          // -> Stream.anyMatch 测试
          // Predicate<Staff> predicateTwo = x -> x.getName() != null &&  x.getName().contains("王");
          // 控制台输出true。 即:stream中存在Staff满足 predicateTwo.
          // System.out.println(stream.anyMatch(predicateTwo));
      
          // -> Stream.noneMatch 测试
          Predicate<Staff> predicateThree = x -> "JustryDeng".equals(x.getName());
          // 控制台输出true。 即:stream中不存在任何Staff满足 predicateThree.
          System.out.println(stream.noneMatch(predicateThree));
      }
      
  • static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)创建一个Stream<T>,其元素是:在第一个流的所有元素后再接上第二个流的所有元素。

    • 示例:
      /**
       * static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b): 创建一个String<T>,其元
       *     素是:在第一个流的所有元素后再接上第二个流的所有元素
       */
      @Test
      public void test3() {
             
             
          // 基础数据准备
          Staff a = Staff.builder().name("张三").age(18).staffNo("NO1").build();
          Staff c = Staff.builder().name("王五").age(40).staffNo("NO3").build();
          Stream<Staff> streamA = Stream.of(a, c);
      
          Staff b = Staff.builder().name("李四").age(25).staffNo("NO2").build();
          Stream<Staff> streamB = Stream.of(b);
      
          // 按前后顺醋,"拼接"两个流
          Stream<Staff> stream = Stream.concat(streamA, streamB);
      
          // 输出:[Staff(name=张三, age=18, staffNo=NO1), Staff(name=王五, age=40, staffNo=NO3), Staff(name=李四, age=25, staffNo=NO2)]
          System.out.println(Arrays.deepToString(stream.toArray()));
      }
      
  • long count()返回此Stream中的元素数量。

    • 示例:
      /**
       * long count: 返回此Stream中的元素数量
       */
      @Test
      public void test4() {
             
             
          // 数据准备
          List<Staff> tmpList = Lists.newArrayList(
                  Staff.builder().name("张三").age(18).staffNo("NO1").build(),
                  Staff.builder().name("李四").age(25).staffNo("NO2").build(),
                  Staff.builder().name("王五").age(40).staffNo("NO3").build()
          );
          Stream<Staff> stream = tmpList.stream();
          // 输出: 3
          System.out.println(stream.count());
      }
      
  • void forEach(Consumer<? super T> action)遍历元素进行消费。

  • void forEachOrdered(Consumer<? super T> action)有序遍历元素进行消费。

    • 注:如果是串行流,使用forEach和使用forEachOrdered都能顺序消费。如果是并行流,使用forEachOrdered能保证有序消费,而forEach不能保证。
    • 示例:
      /**
       * void forEach(Consumer<? super T> action): 遍历元素进行消费
       *
       * void forEachOrdered(Consumer<? super T> action): 有序遍历元素进行消费
       *
       * 注:如果是串行流,使用forEach和使用forEachOrdered都能顺序消费。
       *    如果是并行流,使用forEachOrdered能保证有序消费,而forEach不能保证。
       */
      @Test
      public void test6() {
             
             
          // 数据准备
          List<Integer> tmpList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9);
      
          // 串行流 forEach
          Stream<Integer> sequentialStreamOne = tmpList.stream();
          // 输出: 1   2  3  4  5  6  7  8  9
          sequentialStreamOne.forEach(x -> System.out.print(x + "\t"));
          System.out.print("\n");
      
          // 串行流 forEachOrdered
          Stream<Integer> sequentialStreamTwo = tmpList.stream();
          // 输出: 1   2  3  4  5  6  7  8  9
          sequentialStreamTwo.forEachOrdered(x -> System.out.print(x + "\t"));
          System.out.print("\n");
      
          // 并行流 forEach
          Stream<Integer> parallelStreamOne = tmpList.parallelStream();
          // 输出: 6   5  7  8  9  2  1  4  3
          parallelStreamOne.forEach(x -> System.out.print(x + "\t"));
          System.out.print("\n");
      
          // 并行流 forEachOrdered
          Stream<Integer> parallelStreamTwo = tmpList.parallelStream();
          // 输出: 1   2  3  4  5  6  7  8  9
          parallelStreamTwo.forEachOrdered(x -> System.out.print(x + "\t"));
      }
      
  • Stream<T> distinct()根据equals方法去重。

    • 示例:
      /**
       * Stream<T> distinct: 根据equals方法去重。
       */
      @Test
      @SuppressWarnings("all")
      public void test7() {
             
             
          String a = "JustryDeng";
          String b = new String("JustryDeng");
          String c = "邓帅";
          String d = new String("邓帅");
          // 数据准备
          List<String> tmpList = Lists.newArrayList(a,b, c,d);
          Stream<String> stream = tmpList.parallelStream();
          // 去重
          stream = stream.distinct();
          stream.forEachOrdered(System.out::println);
      }
      
  • Stream<T> filter(Predicate<? super T> predicate)筛选出(只留下)满足predicate的元素。

    • 示例:
      /**
       * Stream<T> filter(Predicate<? super T> predicate): 筛选出(只留下)满足predicate的元素。
       */
      @Test
      public void test8() {
             
             
          // 数据准备
          List<Integer> tmpList = Lists.newArrayList(1, 2,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值