Java8 -- 06 -- Stream类常用方法解析

原文链接:Java8 – 06 – Stream类常用方法解析


相关文章:

  • Java8 – 01 – 行为参数化

  • Java8 – 02 – 函数式接口

  • Java8 – 03 – lambda表达式

  • Java8 – 04 – 引入Stream

  • Java8 – 05 – Collectors类常用方法解析

  • Java8 – 06 – Stream类常用方法解析

  • Java8 – 07 – IntStream类常用方法解析


在了解完 Stream 的定义以及 Collectors 的常用方法之后,我们再来看看 Stream 类的常用方法


  • Student.java

    public class Student {
    
        private String name;
        private int age;
        private double score;
    
        public Student(String name, int age, int score){
            this.name = name;
            this.age = age;
            this.score = score;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public double getScore() {
            return score;
        }
    
        public void setScore(double score) {
            this.score = score;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", score=" + score +
                    '}';
        }
    }
    

一、filter()

  • 接收一个谓词 (一个返回 boolean 的函数) 作为参数,返回一个包括所有符合谓词的元素流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    List<Student> filter = studentList.stream()
        .filter(student -> student.getAge() > 21).collect(toList());
    // [Student(name=小红, age=22, score=80.0), Student(name=小明, age=22, score=82.0)]
    System.out.println(filter);
    

二、distinct()

  • 去除流中重复元素 (根据流中元素的 hashCode() 和 equals() 方法来实现)

    List<Integer> list = Arrays.asList(1, 2, 3, 5, 1, 2, 4);
    List<Integer> distinct = list.stream().distinct().collect(toList());
    System.out.println(distinct); // [1, 2, 3, 5, 4]
    

三、limit()

  • 截断流,返回一个不超过指定长度的流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    List<Student> limit = studentList.stream().limit(1).collect(toList());
    // [Student(name=小白, age=20, score=90.0)]
    System.out.println(limit);
    

四、skip()

  • 跳过元素,返回一个跳过了前 n 个元素的流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    List<Student> skip = studentList.stream().skip(3).collect(toList());
    // [Student(name=小明, age=22, score=82.0)]
    System.out.println(skip);
    

五、map()

  • 接收一个函数作为参数,将该函数应用到流中每个元素上,并将其映射成一个新的元素,返回由新元素组成的流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    List<String> studentNameList = studentList.stream().map(Student::getName).collect(toList());
    System.out.println(studentNameList); // [小白, 小黑, 小红, 小明]
    

六、mapToDouble()

  • 接收一个函数作为参数,将该函数应用到流中每个元素上,并将其映射成一个 double 元素,返回 double 数值流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    DoubleStream doubleStream = studentList.stream().mapToDouble(Student::getScore);
    // [90.0, 95.0, 80.0, 82.0]
    System.out.println(doubleStream.boxed().collect(toList()));
    

七、mapToInt()

  • 接收一个函数作为参数,将该函数应用到流中每个元素上,并将其映射成一个 int 元素,返回 int 数值流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    IntStream intStream = studentList.stream().mapToInt(Student::getAge);
    // [20, 21, 22, 22]
    System.out.println(intStream.boxed().collect(toList()));
    

八、mapToLong()

  • 接收一个函数作为参数,将该函数应用到流中每个元素上,并将其映射成一个 long 元素,返回 long 数值流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    LongStream longStream = studentList.stream().mapToLong(Student::getAge);
    // [20, 21, 22, 22]
    System.out.println(longStream.boxed().collect(toList()));
    

九、flatMap()

  • 如果让我们来获取学生姓名的汉字,而且不能重复 (也就是获得:小, 白, 黑, 红, 明),这该怎么办呢?

  • 一开始我们会想到使用 map,如下所示

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    List<String[]> studentDistinctNameList = studentList.stream()
        .map(student -> student.getName().split("")).distinct().collect(toList());
    studentDistinctNameList.forEach(data -> System.out.println(Arrays.toString(data)));
    
    // [小, 白]
    // [小, 黑]
    // [小, 红]
    // [小, 明]
    
    • 不过这样不行,得到的是一个类型为 String[] 的集合,与我们预期的不符
  • 接着我们想到可以将数组转换为流来处理,如下所示

    List<Stream<String>> studentDistinctNameList = studentList.stream()
        .map(student -> student.getName().split("")).map(Arrays::stream).distinct().collect(toList());
    studentDistinctNameList.forEach(stream -> System.out.println(stream.collect(toList())));
    
    // [小, 白]
    // [小, 黑]
    // [小, 红]
    // [小, 明]
    
    • 这样也不行,得到的是一个类型为 Stream 的集合,与我们预期的不符
  • 最后 flatMap 终于要登场了

    List<String> studentDistinctNameList = studentList.stream()
        .map(student -> student.getName().split(""))
        .flatMap(Arrays::stream).distinct().collect(toList());
    // [小, 白, 黑, 红, 明]
    System.out.println(studentDistinctNameList);
    
    • 现在终于得到与预期相符的结果了,使用 flatMap 的效果是:各个数组并不是各自映射成一个流,而是映射成流的内容,所有使用 map(Arrays::stream) 方法生成的单个流都被合并到了一个流中,即扁平化为了一个流

    • 换句话说就是 flatMap 将多个流连接成了一个流


十、flatMapToDouble()

  • 用法与 flatMap 类似,返回一个 double 数值流

    double[][] data = {{1, 2},{3, 4},{5, 6}};
    DoubleStream doubleStream = Arrays.stream(data).flatMapToDouble(Arrays::stream);
    // [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
    System.out.println(doubleStream.boxed().collect(toList()));
    

十一、flatMapToInt()

  • 用法与 flatMap 类似,返回一个 int 数值流

    int[][] data = {{1, 2},{3, 4},{5, 6}};
    IntStream intStream = Arrays.stream(data).flatMapToInt(Arrays::stream);
    // [1, 2, 3, 4, 5, 6]
    System.out.println(intStream.boxed().collect(toList()));
    

十二、flatMapToLong()

  • 用法与 flatMap 类似,返回一个 long 数值流

    long[][] data = {{1, 2},{3, 4},{5, 6}};
    LongStream longStream = Arrays.stream(data).flatMapToLong(Arrays::stream);
    // [1, 2, 3, 4, 5, 6]
    System.out.println(longStream.boxed().collect(toList()));
    

十三、anyMatch()

  • 检查谓词是否至少匹配流中一个元素

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    boolean anyMatch = studentList.stream().anyMatch(student -> student.getScore() == 95);
    System.out.println(anyMatch); // ture
    
    • 所有学生中只有一个分数为 95,故为 true

十四、allMatch()

  • 检查谓词是否匹配流中所有元素

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    boolean allMatch = studentList.stream().allMatch(student -> student.getScore() > 0);
    System.out.println(allMatch); // true
    
    • 所有学生分数均大于 0,故为 true

十五、noneMatch()

  • 检查谓词是否不匹配流中所有元素

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    boolean noneMatch = studentList.stream().noneMatch(student -> student.getScore() == 100);
    System.out.println(noneMatch); // true
    
    • 所有学生中没有一个分数为 100,故为 true

十六、reduce()

  • 将流归约为单个值,用 Optional 进行包裹

  • 该方法有三个参数

    • U identity

      • 初始值
    • BiFunction accumulator

      • 累加器,将两个元素结合起来生成一个新值
    • BinaryOperator combiner

      • 组合器,将每个线程产生的结果结合起来生成一个新值,只有使用并行流时有用
  • 该方法有三个重载方法,为了方便展示我们将参数类型省去

    • reduce(accumulator)

      List<Student> studentList = new ArrayList<>(Arrays.asList(
              new Student("小白", 20, 90),
              new Student("小黑", 21, 95),
              new Student("小红", 22, 80),
              new Student("小明", 22, 82)));
      
      Optional<Double> reduceOptional = studentList.stream()
          .map(Student::getScore).reduce((x, y) -> x + y);
      System.out.println(reduceOptional.get()); // 347.0
      
      • 此处我们对学生分数进行归约累加
    • reduce(identity, accumulator)

      List<Student> studentList = new ArrayList<>(Arrays.asList(
              new Student("小白", 20, 90),
              new Student("小黑", 21, 95),
              new Student("小红", 22, 80),
              new Student("小明", 22, 82)));
      
      Double reduce = studentList.stream()
          .map(Student::getScore).reduce(3.0, (x, y) -> x + y);
      System.out.println(reduce); // 350.0
      
      • 此处我们以 3.0 作为初始值,然后再对学生分数进行规约累加
    • reduce(identity, accumulator, combiner)

      List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
      Integer reduce = list.parallelStream().reduce(3, (x, y) -> {
          System.out.println("【" + x + "】 + 【" + y + "】 = 【" + (x + y) + "】");
          return x + y;
      }, (x, y) -> {
          System.out.println("【" + x + "】 + 【" + y + "】 = 【" + (x + y) + "】");
          return x + y;
      });
      
      // 【3】 + 【4】 = 【7】
      // 【3】 + 【5】 = 【8】
      // 【3】 + 【3】 = 【6】
      // 【3】 + 【1】 = 【4】
      // 【3】 + 【2】 = 【5】
      
      // 【7】 + 【8】 = 【15】
      // 【4】 + 【5】 = 【9】
      // 【6】 + 【15】 = 【21】
      // 【9】 + 【21】 = 【30】
      System.out.println(reduce); // 30
      
      • 通过输出我们可以很清晰地看到,当使用了并行流 parallelStream 后,会先使用初始值与流中的每个元素进行相加 (应用了第二个参数),然后将得到的结果再相加 (应用了第三个参数),从而得到最终的结果

十七、findFirst()、findAny()

  • findFirst()

    • 返回当前流中的第一个元素
  • findAny()

    • 返回当前流中的任意一个元素
  • 对比说明

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    Optional<Student> serial1 = studentList.stream().findFirst();
    System.out.println(serial1); // Optional[Student(name=小白, age=20, score=90.0)]
    Optional<Student> serial2 = studentList.stream().findAny();
    System.out.println(serial2); // Optional[Student(name=小白, age=20, score=90.0)]
    
    Optional<Student> parallel1 = studentList.parallelStream().findFirst();
    System.out.println(parallel1); // Optional[Student(name=小白, age=20, score=90.0)]
    Optional<Student> parallel2 = studentList.parallelStream().findAny();
    System.out.println(parallel2); // Optional[Student(name=小红, age=22, score=80.0)]
    
    • 当两者在串行流中,返回的都是第一个元素

    • 当两者在并行流中,findFirst 返回的仍然是第一个元素;findAny 在单线程情况下,一般会返回第一个元素,而在多线程环境下,则不能确保返回的是第一个元素


十八、forEach()

  • 循环遍历流中的所有元素 (并行处理)

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    // 小白 小黑 小红 小明
    studentList.stream().map(Student::getName)
        .forEach(name -> System.out.print(name + " "));
    System.out.println();
    // 小红 小明 小黑 小白
    studentList.parallelStream().map(Student::getName)
        .forEach(name -> System.out.print(name + " "));
    
    • 在串行流中,forEach 表现为串行处理

    • 在并行流中,forEach 表现为并行处理


十九、forEachOrdered()

  • 按顺序循环遍历流中的所有元素 (串行处理)

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    // 小红 小明 小白 小黑 
    studentList.parallelStream().map(Student::getName)
        .forEach(name -> System.out.print(name + " "));
    System.out.println();
    // 小白 小黑 小红 小明 
    studentList.parallelStream().map(Student::getName)
        .forEachOrdered(name -> System.out.print(name + " "));
    
    • 在并行流中,forEach 表现为并行处理,输出顺序与添加时不同

    • forEachOrdered 则表现为串行处理,输出顺序与添加时相同


二十、count()

  • 计算流中元素的个数

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    long count = studentList.stream().map(Student::getName).count();
    System.out.println(count); // 4
    

二十一、max()

  • 将流按照指定的比较器筛选出最大元素,用 Optional 进行包裹

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    Optional<Student> studentMaxOptional = studentList.stream()
        .max(comparingDouble(Student::getScore));
    // Student(name=小黑, age=21, score=95.0)
    System.out.println(studentMaxOptional.get());
    

二十二、min()

  • 将流按照指定的比较器筛选出最小元素,用 Optional 进行包裹

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    Optional<Student> studentMinOptional = studentList.stream()
        .min(comparingDouble(Student::getScore));
    // Student(name=小红, age=22, score=80.0)
    System.out.println(studentMinOptional.get());
    

二十三、sorted()

  • 将流中所有元素按照指定规则进行排序

  • 该方法有一个参数

    • Comparator comparator

      • 比较器
  • 该方法有三个重载方法,为了方便展示我们将参数类型省去

    • sorted()

      List<Student> studentList = new ArrayList<>(Arrays.asList(
              new Student("小白", 20, 90),
              new Student("小黑", 21, 95),
              new Student("小红", 22, 80),
              new Student("小明", 22, 82)));
      
      List<Double> sorted = studentList.stream()
          .map(Student::getScore).sorted().collect(toList());
      // [80.0, 82.0, 90.0, 95.0]
      System.out.println(sorted);
      
      • 不加参数默认为升序排序
    • sorted(comparator)

      List<Student> studentList = new ArrayList<>(Arrays.asList(
              new Student("小白", 20, 90),
              new Student("小黑", 21, 95),
              new Student("小红", 22, 80),
              new Student("小明", 22, 82)));
      
      List<Double> sorted = studentList.stream()
          .map(Student::getScore).sorted(reverseOrder()).collect(toList());
      // [95.0, 90.0, 82.0, 80.0]
      System.out.println(sorted);
      

二十四、peek()

  • 接收一个 Consumer 函数作为参数,并将该函数应用到流中每个元素上

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    List<Student> peek = studentList.stream().peek(student ->
        student.setScore(100)).collect(toList());
    // [Student(name=小白, age=20, score=100.0), Student(name=小黑, age=21, score=100.0), 
    // Student(name=小红, age=22, score=100.0), Student(name=小明, age=22, score=100.0)]
    System.out.println(peek);
    
    • 此处我们将所有学生的分数都设置为 100

二十五、toArray()

  • 将流转换为 Object 类型的数组

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    Object[] objects = studentList.stream().toArray();
    // [Student(name=小白, age=20, score=90.0), Student(name=小黑, age=21, score=95.0), 
    // Student(name=小红, age=22, score=80.0), Student(name=小明, age=22, score=82.0)]
    System.out.println(Arrays.toString(objects));
    

二十六、collect()

  • 归约操作,将流中所有元素收集到一个集合中

  • 该方法有三个参数

    • Supplier supplier

      • 供给函数,返回一个空的容器,用于存放数据
    • BiConsumer accumulator

      • 累加器,将元素添加到空容器中
    • BiConsumer combiner

      • 组合器,将每个线程产生的结果相结合,只有使用并行流时有用
  • 该方法有两个重载方法,为了方便展示我们将参数类型省去

    • collect(collector)

      List<Student> studentList = new ArrayList<>(Arrays.asList(
              new Student("小白", 20, 90),
              new Student("小黑", 21, 95),
              new Student("小红", 22, 80),
              new Student("小明", 22, 82)));
      
      List<String> studentNameList = studentList.stream()
          .map(Student::getName).collect(toList());
      // [小白, 小黑, 小红, 小明]
      System.out.println(studentNameList);
      
    • collect(supplier, accumulator, combiner)

      List<Integer> intList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
      LinkedList<Object> collectList = intList.parallelStream()
          .collect(LinkedList::new, (list, i) -> {
          System.out.println("【" + i + "】 + 【2】 = 【" + (i + 2) + "】");
          list.add(i + 2);
      }, (list1, list2) -> {
          List<Object> cache = new ArrayList<>(list1);
          list1.addAll(list2);
          System.out.println("【" + cache + "】.addAll【" + list2 + "】 = 【"+list1+"】");
      });
      
      // 【3】 + 【2】 = 【5】
      // 【1】 + 【2】 = 【3】
      // 【5】 + 【2】 = 【7】
      // 【2】 + 【2】 = 【4】
      // 【4】 + 【2】 = 【6】
      // 【[3]】.addAll【[4]】 = 【[3, 4]】
      // 【[6]】.addAll【[7]】 = 【[6, 7]】
      // 【[5]】.addAll【[6, 7]】 = 【[5, 6, 7]】
      // 【[3, 4]】.addAll【[5, 6, 7]】 = 【[3, 4, 5, 6, 7]】
      System.out.println(collectList); // [3, 4, 5, 6, 7]
      
      • 通过输出我们可以很清晰地看到,当使用了并行流 parallelStream 后,会先使用一个空的集合去添加元素 (应用了第二个参数),然后将得到的结果在添加到一起 (应用了第三个参数),从而得到最终的结果

二十七、close()

  • 关闭流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
            
    Stream<Student> stream = studentList.stream();
    stream.close();
    stream.forEach(System.out::println);
    
    • 同个流只能被消费一次,当流被关闭后再使用流会报错

      image


二十八、isParallel()

  • 判断流是否为并行流,如果是则为 true,不是则为 false

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    System.out.println(studentList.stream().isParallel()); // false
    System.out.println(studentList.parallelStream().isParallel()); // true
    

二十九、parallel()

  • 返回并行的等效流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
            
    System.out.println(studentList.stream().parallel().isParallel()); // true
    

三十、onClose()

  • 返回具有附加关闭处理程序的等效流

  • 即当调用 close() 方法关闭流后会自动执行 onClose() 方法中添加的操作

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
            
    Stream<Student> stream = studentList.stream()
        .onClose(() -> System.out.println("Hello World"));
    stream.close();  // Hello World
    

三十一、iterator()

  • 返回流的元素迭代器

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    Iterator<String> iterator = studentList.stream().map(Student::getName).iterator();
    while (iterator.hasNext()) {
        System.out.print(iterator.next() + " ");
    }
    // 小白 小黑 小红 小明
    

三十二、sequential()

  • 返回顺序的等效流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    // 小红 小明 小白 小黑 
    studentList.parallelStream().map(Student::getName)
        .forEach(name -> System.out.print(name + " "));
    System.out.println();
    // 小白 小黑 小红 小明 
    studentList.parallelStream().map(Student::getName).
        sequential().forEach(name -> System.out.print(name + " "));
    

三十三、unordered()

  • 返回无序的等效流

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    // 小红 小明 小黑 小白 
    studentList.parallelStream().map(Student::getName)
        .forEach(name -> System.out.print(name + " "));
    System.out.println();
    // 小红 小白 小明 小黑 
    studentList.parallelStream().map(Student::getName).
        unordered().forEach(name -> System.out.print(name + " "));
    

三十四、spliterator()

  • 返回流的可分割迭代器 (是 Java 为了并行遍历数据源中的元素而设计的迭代器)

    List<Student> studentList = new ArrayList<>(Arrays.asList(
            new Student("小白", 20, 90),
            new Student("小黑", 21, 95),
            new Student("小红", 22, 80),
            new Student("小明", 22, 82)));
    
    Spliterator<Student> spliterator = studentList.stream().spliterator();
    // Student(name=小白, age=20, score=90.0)
    // Student(name=小黑, age=21, score=95.0)
    // Student(name=小红, age=22, score=80.0)
    // Student(name=小明, age=22, score=82.0)
    spliterator.forEachRemaining(System.out::println);
    

三十五、Stream.of()

  • 根据传入的元素构建顺序流

  • 该方法有两个重载方法

    • of(T t)

      • 返回包含单个元素的顺序流

        Stream.of(1).forEach(System.out::print); // 1
        
    • of(T… values)

      • 返回包含多个元素的顺序流

        Stream.of(1, 2, 3).forEach(System.out::print); // 123
        

三十六、Stream.empty()

  • 返回一个空的顺序流

    Stream<Object> empty = Stream.empty();
    System.out.println(empty.collect(toList())); // []
    

三十七、Stream.concat()

  • 合并两个流

  • 如果两个输入流都是串行流的,则得到的结果流是有序的;如果任何一个输入流是并行流,则得到的结果流是无序的

    List<Integer> list1 = Arrays.asList(1, 2, 3);
    List<Integer> list2 = Arrays.asList(4, 5, 6);
    // 123456
    Stream.concat(list1.stream(), list2.stream()).forEach(System.out::print);
    System.out.println();
    // 465123
    Stream.concat(list1.stream(), list2.parallelStream()).forEach(System.out::print);
    

三十八、Stream.builder()

  • 返回流的构造器

    Stream.Builder<Object> builder = Stream.builder();
    System.out.println(builder.build().collect(toList())); // []
    

三十九、Stream.iterate()

  • 返回一个无限流,需要截断

  • 该方法有两个参数

    • final T seed

      • 初始元素
    • final UnaryOperator f

      • 累加器,将该函数应用于上一个元素来生成新元素
  • 该方法有一个重载方法,为了方便展示我们将参数类型省去

    • iterate(seed, f)

      Stream.iterate(0, n -> n + 2).limit(5).forEach(System.out::print); // 02468
      

四十、Stream.generate()

  • 返回一个无限流,接收一个供给函数作为参数,来提供新值,需要截断

    // 0.5393030689484258
    // 0.2915922391351988
    // 0.8025149159858009
    // 0.7681873637828662
    // 0.8158901245174043
    Stream.generate(Math::random).limit(5).forEach(System.out::println); 
    

你可能感兴趣的:(Java)