Fork me on GitHub

StreamAPI终止操作

何为终止操作

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

查找与匹配

1.allMatch–检查是否匹配所有元素

@Test
public void test9(){
    //allMatch--检查是否匹配所有元素
    boolean b = employees.stream()
            .allMatch((e) -> e.getStatus().equals(Employee.Status.FREE));
    System.out.println(b);//false
}

2.anyMatch–检查是否至少匹配一个元素

@Test
public void test9(){
    //anyMatch--检查是否至少匹配一个元素
    boolean b1 = employees.stream()
            .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
    System.out.println(b1);//true
}

3.noneMatch–检查是否没有匹配所有元素

@Test
public void test9(){
    //noneMatch--检查是否没有匹配所有元素
    boolean b2 = employees.stream()
            .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
    System.out.println(b2);//false
}

4.findFirst–返回第一个元素

@Test
public void test9(){
    //findFirst--返回第一个元素
    Optional<Employee> op = employees.stream()
            .sorted((e1, e2) -> -Double.compare(e1.getSalary(), e2.getSalary()))
            .findFirst();
    System.out.println(op.get());}

5.findAny–返回当前流中任意元素

@Test
public void test9(){
    //findAny--返回当前流中任意元素
   Optional<Employee> op2 = employees.parallelStream()
            .filter((e) -> e.getStatus().equals(Employee.Status.FREE))
            .findAny();
    System.out.println(op2.get());
}

6.count–返回流中元素的总个数

@Test
public void test9(){
    //count--返回流中元素的总个数
    long count = employees.stream().count();
    System.out.println(count);
}

7.max–返回流中最大值

@Test
public void test9(){
    //max--返回流中最大值
    Optional<Employee> op3 = employees.stream()
            .max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
    System.out.println(op3.get());
}

8.min–返回流中最小值

@Test
public void test9(){
   //min--返回流中最小值
    Optional<Double> op4 = employees.stream()
            .map(Employee::getSalary)
            .min(Double::compareTo);
    System.out.println(op4.get());
}

规约

reduce(T identity,BinaryOperator)/reduce(BinaryOPerator)–可以将流中元素反复结合起来,得到一个值

@org.junit.Test
public void test3(){
    List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

    Integer reduce = list.stream()
            .reduce(0, (x, y) -> x + y);

    System.out.println(reduce);

    System.out.println("-------------------------------");
    //计算所有工资
    Optional<Double> reduce1 = employees.stream()
            .map(Employee::getSalary)
            .reduce(Double::sum);
    System.out.println(reduce1.get());

    System.out.println("-------------------------------");

    Optional<Integer> reduce2 = employees.stream().map(Employee::getAge).reduce(Integer::max);
    System.out.println(reduce2.get());
}

备注

map和reduce的连接通常称为map-reduce模式,因Goolge用它来进行网络搜索而出名

收集

collect:将流转换为其他形式,接受一个Collector接口的实现,用于给Stream中元素做汇总的方法

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

1.toList:返回类型List,把流中元素收集到List中
@Test
public void test9(){
   //toList:返回类型List<T>,把流中元素收集到List中
    List<String> collect = employees.stream()
            .map(Employee::getName)
            .collect(Collectors.toList());
    System.out.println(collect);
}
2.toSet:返回类型Set,把流中元素收集到Set中
@Test
public void test9(){
   //toSet:返回类型Set<T>,把流中元素收集到Set中
    Set<String> collect1 = employees.stream()
            .map(Employee::getName)
            .collect(Collectors.toSet());
    System.out.println(collect1);
}
3.toCollection: 返回类型Collection,把流中元素收集到创建的集合、
@Test
public void test9(){
   //toCollection: 返回类型Collection<T>,把流中元素收集到创建的集合
    ArrayList<Integer> collect2 = employees.stream()
            .map(Employee::getAge)
            .collect(Collectors.toCollection(ArrayList::new));
    System.out.println(collect2);
}
4.counting:返回类型Long,计算流中总元素
@Test
public void test9(){
   //counting:返回类型Long,计算流中总元素
    Long collect3 = employees.stream()
            //.map(Employee::getAge)
            .collect(Collectors.counting());
    System.out.println(collect3);
}
5.averagingDouble:计算流中平均值
@Test
public void test9(){
   //averagingDouble:计算流中平均值
    Double aDouble = employees.stream()
            .collect(Collectors.averagingDouble(Employee::getSalary));
    System.out.println(aDouble);
}
6.summingDouble:计算流中总和
@Test
public void test9(){
    //summingDouble:计算流中总和
    Integer collect4 = employees.stream()
            .collect(Collectors.summingInt(Employee::getAge));
    System.out.println(collect4);
}
7.maxBy:返回类型Optional:根据比较器选择最大值
@Test
public void test9(){
    //maxBy:返回类型Optional<T>:根据比较器选择最大值
    Optional<Employee> op = employees.stream()
            .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
    System.out.println(op.get());
}
8.minBy:返回类型Optional:根据比较器选择最小值
@Test
public void test9(){
     //minBy:返回类型Optional<T>:根据比较器选择最小值
    Optional<Integer> op2 = employees.stream()
            .map(Employee::getAge)
            .collect(Collectors.minBy(Integer::compare));
    System.out.println(op2.get());
}
8.groupingBy:范会类型Map>根据属型值对流分组
@Test
public void test9(){
    //groupingBy:范会类型Map<k,List<t>>根据属型值对流分组
    Map<Employee.Status, List<Employee>> collect5 = employees.stream()
            .collect(Collectors.groupingBy(Employee::getStatus));
    System.out.println(collect5);

    //{BUSY=[Employee{name='李四', age=58, salary=5555.55, status=BUSY}, Employee{name='田七', age=23, salary=8888.88, status=BUSY}], FREE=[Employee{name='张三', age=18, salary=9999.99, status=FREE}, Employee{name='赵六', age=36, salary=6666.66, status=FREE}], VOCATION=[Employee{name='王五', age=26, salary=3333.33, status=VOCATION}]}
}
9.多级分组
@Test
public void test9(){
    //多级分组
    Map<Employee.Status, Map<String, List<Employee>>> collect6 = employees.stream()
            .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((Employee e) -> {
                if (e.getAge() <= 35) {
                    return "青年";
                } else if (e.getAge() <= 50) {
                    return "中年";
                } else {
                    return "老年";
                }
            })));
    System.out.println(collect6);

    //{BUSY={青年=[Employee{name='田七', age=23, salary=8888.88, status=BUSY}], 老年=[Employee{name='李四', age=58, salary=5555.55, status=BUSY}]}, FREE={青年=[Employee{name='张三', age=18, salary=9999.99, status=FREE}], 中年=[Employee{name='赵六', age=36, salary=6666.66, status=FREE}]}, VOCATION={青年=[Employee{name='王五', age=26, salary=3333.33, status=VOCATION}]}}
}
10.//partitioningBy:返回类型Map>,根据true或者false进行分组
@Test
public void test9(){
     //partitioningBy:返回类型Map<Boolean,List<T>>,根据true或者false进行分组
    Map<Boolean, List<Employee>> collect7 = employees.stream()
            .collect(Collectors.partitioningBy((e) -> e.getSalary() > 8000));
    System.out.println(collect7);
}
11.sumarizingDouble:返回类型DoubleSummaryStatistics,收集流中Double属性的统计值
@Test
public void test9(){
     //sumarizingDouble:返回类
    DoubleSummaryStatistics,收集流中Double属性的统计值
    DoubleSummaryStatistics statistics = employees.stream()
            .collect(Collectors.summarizingDouble(Employee::getSalary));
    System.out.println(statistics.getCount());
    System.out.println(statistics.getSum());
}
12.joining:返回类型String,连接流中每个字符串
@Test
public void test9(){
    //joining:返回类型String,连接流中每个字符串
    String s = employees.stream()
            .map(Employee::getName)
            .collect(Collectors.joining(",", "---", "---"));
    System.out.println(s);
}