Skip to content
生如风生如风
主页
github icon
  • Stream
    • 中间操作
      • 终止操作

      Java—java8Stream

      author icon生如风calendar icon2022年7月28日category icon
      • Java
      tag icon
      • Java
      timer icon大约 7 分钟

      此页内容
      • Stream
        • 中间操作
        • 终止操作

      [TOC]

      记录下java的一些Stream用法。。。

      # Java8Stream

      # Stream

      用来测试的类    Employee

      public class Employee {
          private String name;  // 姓名
          private int salary; // 薪资
          private int age; // 年龄
          private String sex; //性别
          private String area;  // 地区
          private Status status;
      
          public Employee() {
          }
      
          public Employee(String name, int salary, int age, String sex, String area) {
              this.name = name;
              this.salary = salary;
              this.age = age;
              this.sex = sex;
              this.area = area;
          }
      
          public Employee(String name, int salary, int age, String sex, String area, Status status) {
              this.name = name;
              this.salary = salary;
              this.age = age;
              this.sex = sex;
              this.area = area;
              this.status = status;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              Employee employee = (Employee) o;
              return salary == employee.salary &&
                      age == employee.age &&
                      Objects.equals(name, employee.name) &&
                      Objects.equals(sex, employee.sex) &&
                      Objects.equals(area, employee.area);
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(name, salary, age, sex, area);
          }
      
          @Override
          public String toString() {
              return "Employee{" +
                      "name='" + name + '\'' +
                      ", salary=" + salary +
                      ", age=" + age +
                      ", sex='" + sex + '\'' +
                      ", area='" + area + '\'' +
                      '}';
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getSalary() {
              return salary;
          }
      
          public void setSalary(int salary) {
              this.salary = salary;
          }
      
          public int getAge() {
              return age;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          public String getSex() {
              return sex;
          }
      
          public void setSex(String sex) {
              this.sex = sex;
          }
      
          public String getArea() {
              return area;
          }
      
          public void setArea(String area) {
              this.area = area;
          }
      
          public Status getStatus() {
              return status;
          }
      
          public void setStatus(Status status) {
              this.status = status;
          }
      
          public enum  Status{
              FREE,BUSY,VOCATION
          }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108

      初始化测试对象

      List<Employee> emps = Arrays.asList(
           new Employee("张三", 10000, 25, "男", "海南", Employee.Status.FREE),
           new Employee("李四", 20000, 26, "女", "浙江", Employee.Status.BUSY),
           new Employee("王五", 15000, 28, "男", "海南", Employee.Status.VOCATION),
           new Employee("赵六", 15600, 28, "男", "海南", Employee.Status.FREE),
           new Employee("赵六", 20000, 51, "女", "广东", Employee.Status.VOCATION));"));
      
      1
      2
      3
      4
      5
      6

      # 中间操作

      # filter

      /**  
       * filter()   接收lambda,从流中排除某些元素,获取条件符合的元素  
       */  
      @Test  
      public void test1() {  
         Stream<Employee> stream = list.stream().filter((e) -> e.getAge() > 25);    
         stream.forEach(System.out::println);  
      }
      
      结果:
      Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}
      Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}
      Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}
      Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14

      # limit

      /**
       * limit()  截断流,使其不超过指定量
       */
      @Test
      public void test2() {
          Stream<Employee> stream = emps.stream().limit(1);
          stream.forEach(System.out::println);
      }
      
      结果:
      Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11

      # skip

      /**
       * skip()   跳过指定的个数,返回后续的流,与limit互补
       */
      @Test
      public void test3() {
          Stream<Employee> stream = emps.stream().skip(2);
          stream.forEach(System.out::println);
      }
      
      结果:
      Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}
      Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}
      Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13

      # distinct

      /**
       * distinct()
       * 通过流所生成的元素的hashcode和equals去除重复元素,需要流对应的对象重写hashcode和equals
       */
      @Test
      public void test4() {
          emps.stream().distinct().forEach(System.out::println);
      }
      
      1
      2
      3
      4
      5
      6
      7
      8

      # map

      /**
           * map()
           * 接收lambda,将元素转换成其他元素或提取信息。
           * 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新元素
           * 类似:add
           */
          @Test
          public void test5() {
              List<String> strs = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
              strs.stream().map((str) -> str.toUpperCase()).forEach(System.out::println);
      
              System.out.println("------------------------");
      
              emps.stream().map((e) -> e.getName()).forEach(System.out::println);
              emps.stream().map(Employee::getName).forEach(System.out::println);
      
              System.out.println("------------------------");
      
              // map中处理的是aaa,bbb,ccc每次传入的,然后返回一个流,于是就返回了多个流,放入一个流中
              Stream<Stream<Character>> stream = strs.stream().map(TestStreamApi::filterCharacter);
              stream.forEach((s) -> s.forEach(System.out::println));
      
          }
      
          public static Stream<Character> filterCharacter(String str) {
              ArrayList<Character> list = new ArrayList<>();
              for (Character c : str.toCharArray()) {
                  list.add(c);
              }
              return list.stream();
          }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31

      # flatMap

      /**
       * flatMap
       * 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
       * 类似:addAll
       */
      @Test
      public void test6() {
          List<String> strs = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
          Stream<Character> stream = strs.stream().flatMap(TestStreamApi::filterCharacter);
          stream.forEach(System.out::println);
      }
      
      结果:
      a
      a
      a
      b
      b
      b
      c
      c
      c
      d
      d
      d
      e
      e
      e
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28

      # sort

      /**
       * 排序
       * sort()——自然排序(Comparable)
       * sort(Comparator com)——定制排序(Comparator)
       */
      @Test
      public void test7() {
          List<String> strs = Arrays.asList("ccc", "eee", "aaa", "ddd", "bbb");
          strs.stream().sorted().forEach(System.out::println);
      
          System.out.println("-------------------");
          Stream<Employee> stream = emps.stream().sorted((e1, e2) -> {
              if (e1.getAge() == e2.getAge()) {
                  return e1.getName().compareTo(e2.getName());
              } else {
                  return e1.getAge();
              }
          });
          stream.forEach(System.out::println);
      }
      
      结果:
      aaa
      bbb
      ccc
      ddd
      eee
      -------------------
      Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}
      Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}
      Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}
      Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}
      Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33

      # 终止操作

      # allMatch

      /**
       * allMatch   检查是否匹配所有元素
       * 需要所有元素有,就返回true
       */
      @Test
      public void test() {
          boolean b = emps.stream().allMatch(employee -> employee.getStatus().equals(Employee.Status.BUSY));
          System.out.println(b);
      }
      
      结果:
      false
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12

      # anyMatch

      /**
       * anyMatch     检查是否匹配任意一个元素
       * 其中之一有,就返回true
       */
      @Test
      public void test2() {
          boolean b = emps.stream().anyMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
          System.out.println("b = " + b);
      }
      
      结果:
      b=true
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12

      # noneMatch

      /**
           * noneMatch    检查所有元素,没有一个元素匹配
           */
          @Test
          public void test3() {
              boolean b = emps.stream().noneMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
              System.out.println("b = " + b);
      
          }
      
      结果:
      b = false
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12

      # findFirst 和 findAny

      /**
           * findFirst    返回当前流的第一个元素
           * findAny      返回当前流的任意一个元素
           */
          @Test
          public void test4() {
              Optional<Employee> op = emps.stream()
                      .sorted((e1, e2) -> -Double.compare(e1.getSalary(), e2.getSalary()))
                      .findFirst();
              System.out.println("employee = " + op.get());
      
              System.out.println("-----------------");
              Optional<Employee> op1 = emps.parallelStream().filter(e -> e.getStatus().equals(Employee.Status.FREE)).findAny();
              System.out.println("employee1 = " + op1.get());
          }
      
      结果:
      employee = Employee{name='002', salary=20000, age=26, sex='女', area='浙江'}
      -----------------
      employee1 = Employee{name='003', salary=15600, age=28, sex='男', area='海南'}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20

      # count、max和min

      /**
           * count    返回当前流的元素个数
           * max      返回当前流的最大值
           * min      返回当前流的最小值
           */
          @Test
          public void test5() {
              long count = emps.stream().count();
              System.out.println("count = " + count);
      
              Optional<Employee> op = emps.stream().max((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
              System.out.println("op = " + op.get());
      
              Optional<Employee> op1 = emps.stream().min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
              System.out.println("op1 = " + op1.get());
          }
      
      结果:
      count = 4
      op = Employee{name='004', salary=15000, age=28, sex='男', area='海南'}
      op1 = Employee{name='001', salary=10000, age=25, sex='男', area='海南'}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21

      # reduce

      /**
           * 规约  reduce,可以将流中元素反复结合起来,得到一个新值
           */
          @Test
          public void test() {
              List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
              // 将参数1 identity作为x,将list中的元素作为y,执行x+y,在将结果作为x,list中的下一个元素作为y反复执行
              Integer sum = list.stream().reduce(1, (x, y) -> x + y);
              System.out.println("sum = " + sum);
      
              System.out.println("-------------------");
              Integer sum2 = emps.stream().map(Employee::getSalary).reduce(0, (x, y) -> x + y);
              System.out.println("sum2 = " + sum2);
      
              Optional<Integer> op = emps.stream().map(Employee::getSalary).reduce(Integer::sum);
              System.out.println("op.get() = " + op.get());
          }
      
      结果:
      sum = 56
      -------------------
      sum2 = 80600
      op.get() = 80600
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23

      # collect

      /**
           * 搜集  collect,将流转换为其他形式。接收一个Collectors接口的实现,用于给Stream中元素做汇总方法
           */
          @Test
          public void test2() {
              List<String> list = emps.stream().map(Employee::getName).collect(Collectors.toList());
              for (String s : list) {
                  System.out.println(s);
              }
      
              System.out.println("---------------------------------");
              Set<String> set = emps.stream().map(Employee::getName).collect(Collectors.toSet());
              set.forEach(System.out::println);
      
              System.out.println("--------------总数-------------------");
              Long count = emps.stream().collect(Collectors.counting());
              System.out.println("count = " + count);
      
              System.out.println("--------------平均数-------------------");
              Double average = emps.stream().collect(Collectors.averagingInt(Employee::getAge));
              System.out.println("average = " + average);
          }
      
      结果:
      张三
      李四
      王五
      赵六
      赵六
      ---------------------------------
      李四
      张三
      王五
      赵六
      --------------总数-------------------
      count = 5
      --------------平均数-------------------
      average = 31.6
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      // 分组
          @Test
          public void test3() {
              Map<Employee.Status, List<Employee>> map = emps.stream().collect(Collectors.groupingBy(e -> e.getStatus()));
              Map<Employee.Status, List<Employee>> map1 = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));
              System.out.println("map = " + map);
              System.out.println("map1 = " + map1);
          }
      
      结果:
      map = {FREE=[Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}, Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}], VOCATION=[Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}, Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}], BUSY=[Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}]}
      map1 = {FREE=[Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}, Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}], VOCATION=[Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}, Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}], BUSY=[Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}]}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      // 多级分组
          @Test
          public void test4() {
              Map<Employee.Status, Map<String, List<Employee>>> map = emps.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
                          if (e.getAge() <= 35) {
                              return "青年";
                          } else if (e.getAge() <= 50) {
                              return "中年";
                          } else {
                              return "老年";
                          }
                      }
              )));
              System.out.println("map = " + map);
          }
      
      结果:
      map = {VOCATION={青年=[Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}], 老年=[Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}]}, BUSY={青年=[Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}]}, FREE={青年=[Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}, Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}]}}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      // 分片
          @Test
          public void test5() {
              Map<Boolean, List<Employee>> map = emps.stream().collect(Collectors.partitioningBy(e -> e.getSalary() > 20000));
              System.out.println("map = " + map);
          }
      
      结果:
      map = {false=[Employee{name='张三', salary=10000, age=25, sex='男', area='海南'}, Employee{name='李四', salary=20000, age=26, sex='女', area='浙江'}, Employee{name='王五', salary=15000, age=28, sex='男', area='海南'}, Employee{name='赵六', salary=15600, age=28, sex='男', area='海南'}, Employee{name='赵六', salary=20000, age=51, sex='女', area='广东'}], true=[]}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      // 连接
          @Test
          public void test6() {
              String s = emps.stream()
                      .map(Employee::getName).collect(Collectors.joining(","));
              System.out.println("s = " + s);
          }
      
      结果:
      s = 张三,李四,王五,赵六,赵六
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10

      关于stream使用暂时记录到这,后续遇到的也记录进来

      可以看看我的学习——基于Hexo的个人博客: 网站:http://www.fuzm.wangopen in new window ————————————————————————— 作为初学者,很多知识都没有掌握,见谅,如有错误请指出,以期进步,感谢!。后续有新的学习,继续补充上来。

      默认页脚
      Copyright © 2026 生如风