千家信息网

Java8中Stream API如何终止

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章主要为大家展示了"Java8中Stream API如何终止",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Java8中Stream API如何终止"
千家信息网最后更新 2025年02月01日Java8中Stream API如何终止

这篇文章主要为大家展示了"Java8中Stream API如何终止",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Java8中Stream API如何终止"这篇文章吧。

1.写在前面

我们都知道Stream API完成的操作是需要三步的:创建Stream → 中间操作 → 终止操作。那么这篇文章就来说一下终止操作。

2.终止操作

终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。

2.1 终止操作之查找与匹配

首先,我们仍然需要一个自定义的Employee类,以及一个存储它的List集合。

在Employee类定义了枚举(BUSY:忙碌;FREE:空闲;VOCATION:休假)

package com.szh.java8; import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor; /** * */@Data@NoArgsConstructor@AllArgsConstructorpublic class Employee2 {     private Integer id;    private String name;    private Integer age;    private Double salary;    private Status status;     public Employee2(Integer id) {        this.id = id;    }     public Employee2(Integer id, String name) {        this.id = id;        this.name = name;    }     public enum Status {        FREE,        BUSY,        VOCATION    } }
List employees = Arrays.asList(            new Employee2(1001,"张三",26,6666.66, Employee2.Status.BUSY),            new Employee2(1002,"李四",50,1111.11,Employee2.Status.FREE),            new Employee2(1003,"王五",18,9999.99,Employee2.Status.VOCATION),            new Employee2(1004,"赵六",35,8888.88,Employee2.Status.BUSY),            new Employee2(1005,"田七一",44,3333.33,Employee2.Status.FREE),            new Employee2(1005,"田七二",44,3333.33,Employee2.Status.VOCATION),            new Employee2(1005,"田七七",44,3333.33,Employee2.Status.BUSY)    );

查找所有的员工是否都处于BUSY状态、至少有一个员工处于FREE状态、没有员工处于VOCATION状态。

@Test    public void test1() {        boolean b1 = employees.stream()                .allMatch((e) -> e.getStatus().equals(Employee2.Status.BUSY));        System.out.println(b1);         boolean b2 = employees.stream()                .anyMatch((e) -> e.getStatus().equals(Employee2.Status.FREE));        System.out.println(b2);         boolean b3 = employees.stream()                .noneMatch((e) -> e.getStatus().equals(Employee2.Status.VOCATION));        System.out.println(b3);    }

对员工薪资进行排序之后,返回第一个员工的信息; 筛选出BUSY状态员工之后,返回任意一个处于BUSY状态的员工信息。

@Test    public void test2() {        Optional op1 = employees.stream()                .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))                .findFirst();        System.out.println(op1.get());         System.out.println("----------------------------------");         Optional op2 = employees.stream()                .filter((e) -> e.getStatus().equals(Employee2.Status.BUSY))                .findAny();        System.out.println(op2.get());    }

下面,我们来看一下另外一组查找与匹配的方法。

计算处于VOCATION状态的员工数量;对员工薪资字段进行映射,同时获取其中的最高薪资;获取年龄最小的员工信息。

@Test    public void test3() {        long count = employees.stream()                .filter((e) -> e.getStatus().equals(Employee2.Status.VOCATION))                .count();        System.out.println(count);         Optional op1 = employees.stream()                .map(Employee2::getSalary)                .max(Double::compare);        System.out.println(op1.get());         Optional op2 = employees.stream()                .min((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));        System.out.println(op2.get());    }

在这里,大家需要注意的一点就是:当前Stream流一旦进行了终止操作,就不能再次使用了。

我们看下面的代码案例。(异常信息说的是:stream流已经被关闭了)

@Test    public void test4() {        Stream stream = employees.stream()                .filter((e) -> e.getStatus().equals(Employee2.Status.BUSY));        long count = stream.count();         stream.map(Employee2::getName);    }

2.2 终止操作之归约与收集

Collector 接口中方法的实现决定了如何对流执行收集操作 (如收集到 List、Set、Map) 。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

计算整数1~10的和;对员工薪资字段进行映射,之后获取所有员工的薪资总和。

@Test    public void test1() {        List list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);        Integer sum = list.stream()                .reduce(0, (x, y) -> x + y);        System.out.println(sum);         System.out.println("-------------------------------");         Optional optional = employees.stream()                .map(Employee2::getSalary)                .reduce(Double::sum);        System.out.println(optional.get());    }

依次对我们先前定义好的存储员工信息的List集合 做name字段的映射,然后 转为 List、Set、HashSet(使用 Collectors 实用类中的静态方法即可完成)。

在Set、HashSet集合中,由于元素是无序、不可重复的,所以只有一个田七二。

@Test    public void test2() {        List list = employees.stream()                .map(Employee2::getName)                .collect(Collectors.toList());        list.forEach(System.out::println);         System.out.println("-------------------------------");         Set set = employees.stream()                .map(Employee2::getName)                .collect(Collectors.toSet());        set.forEach(System.out::println);         System.out.println("-------------------------------");         HashSet hashSet = employees.stream()                .map(Employee2::getName)                .collect(Collectors.toCollection(HashSet::new));        hashSet.forEach(System.out::println);    }

对员工薪资字段做映射,之后通过比较器获取最高薪资;

不做映射处理,直接通过比较器获取薪资最低的员工信息;

计算所有员工的薪资总和;

计算所有员工的平均薪资;

计算员工总数;

对员工薪资字段做映射,之后通过比较器获取最高薪资;

@Test    public void test3() {        Optional max = employees.stream()                .map(Employee2::getSalary)                .collect(Collectors.maxBy(Double::compare));        System.out.println(max.get());         Optional min = employees.stream()                .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));        System.out.println(min.get());         Double sum = employees.stream()                .collect(Collectors.summingDouble(Employee2::getSalary));        System.out.println(sum);         Double avg = employees.stream()                .collect(Collectors.averagingDouble(Employee2::getSalary));        System.out.println(avg);         Long count = employees.stream()                .collect(Collectors.counting());        System.out.println(count);         DoubleSummaryStatistics dss = employees.stream()                .collect(Collectors.summarizingDouble(Employee2::getSalary));        System.out.println(dss.getMax());    }

单个条件分组:根据员工状态对Stream流进行分组。 因为分组之后得到的是一个Map集合,key就是员工状态,value则是一个List集合。

@Test    public void test4() {        Map> map = employees.stream()                .collect(Collectors.groupingBy(Employee2::getStatus));         Set>> set = map.entrySet();        Iterator>> iterator = set.iterator();        while (iterator.hasNext()) {            Map.Entry> entry = iterator.next();            System.out.println(entry.getKey());            System.out.println(entry.getValue());        }    }

多个条件分组:先按照员工状态分组,如果状态相同,再按照员工年龄分组。

@Test    public void test5() {        Map>> map = employees.stream()                .collect(Collectors.groupingBy(Employee2::getStatus, Collectors.groupingBy((e) -> {                    if (e.getAge() <= 35) {                        return "成年";                    } else if (e.getAge() <= 60) {                        return "中年";                    } else {                        return "老年";                    }                })));         Set set = map.keySet();        Iterator iterator = set.iterator();        while (iterator.hasNext()) {            Employee2.Status next = iterator.next();            Map> listMap = map.get(next);            System.out.println(next);            System.out.println(listMap);        }    }

根据特定的条件对员工进行分区处理。(员工薪资大于等于5000为 true 分区;否则都为 false 分区)。

@Test    public void test6() {        Map> map = employees.stream()                .collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));        map.forEach((key,value) -> System.out.println("键:" + key + ", 值:" + value));    }

以上是"Java8中Stream API如何终止"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0