以下几种常用的Stream终止操作,map-reduce模式比较常用,collect比较强大
1、allMatch, anyMatch,noneMatch 匹配
三个方法均返回 boolean
allMatch---检查是否匹配所有元素anyMatch----检查是否匹配任意元素 noneMatch---检查是否没有匹配所有元素
还是以employee类为例,增加一个属性 枚举status
List employees = Arrays.asList(
new Employee( "李四", 59, 6666.66,Status.FREE),
new Employee("张三", 18, 9999.99,Status.BUSY),
new Employee( "王五", 28, 3333.33,Status.VOCATION),
new Employee("赵六", 8, 7777.77,Status.FREE),
new Employee("赵六", 8, 7777.77,Status.BUSY),
new Employee("赵六", 8, 7777.77,Status.VOCATION),
new Employee( "田七", 38, 5555.55,Status.FREE)
);
boolean b1=employees.stream()
.allMatch((e)->e.getStatus()==Status.FREE);
boolean b2=employees.stream()
.anyMatch((e)->e.getStatus()==Status.BUSY);
boolean b3=employees.stream()
.noneMatch((e)->e.getAge()>10);
System.out.println(b1+"\t"+b2+"\t"+b3);
System.out.println("--------------------------");
Optional op1=employees.stream()
.sorted((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary()))
.findFirst();
print(op1.get());
System.out.println("--------------------------");
Optional op2=employees.stream()
.filter(e->e.getStatus()==Status.FREE)
.findAny();
print(op2.get());
false true false
--------------------------
王五 28 3333.33 VOCATION
--------------------------
李四 59 6666.66 FREE
这两个终止方法返回的是 Optional
Optional是封装对象的容器类,如果该对象是个null,那么通过op.orElse(other)来选一个指定的对象替代空对象,比如
op2.orElse(new Employee("a",14,2222,Status.FREE));
如果经过findFirst之后并没有找到一个非空的对象,那么在调用get获取对象时返回的是other,就是新建的名字为'a‘的类
对于Stream 如果调用的方法返回值有可能为空时,那么它的返回值都是Optional
findAny是随便取出一个符合要求的,在并行流下特别明显,并行流parallelStream()
(3)count, max min
count没有多余可说,max和min反回的是Optional
Java8为Comparator接口提供一个新的静态方法comparing()该方法接收一个lambda函数并返回一个函数,什么意思,例如op4
调用Comparator中的comparing 进行比较这个比较是遵从后面的表达式进行的。
Optional op3=employees.stream()
.max((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary()));
//
print(op3.get());
System.out.println("--------------------------");
Optional op4=employees.stream()
.min(Comparator.comparing(e->e.getName().length()));
print(op4.get());
--------------------------
张三 18 9999.99 BUSY
--------------------------
六 8 7777.77 VOCATION
public static > Comparator comparing(
Function super T, ? extends U> keyExtractor)
{
Objects.requireNonNull(keyExtractor);
return (Comparator & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
从一组值中生成一个值,比如对于序列求和 ,这里值得注意的有三点:
注意:(1)reduce运算的过程是,比如拿sum距离,首先0最为x,1作为y,它们的结果0+1=1作为x,2作为y,结果3作为x,3作为y,结果6作为x,4作为y。
(2)reduce的返回值有时候是Optional封装的对象,因为上述运算情况,所以在指定了identity(起始值)的情况下,正常返回,如果没有指定那么就有可能出现空指针,所以返回的是Optional
(3)在例子2中用到了map-reduce这种模式,该模式在大数据处理中常用到
List l1=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
int sum=l1.stream()
.reduce(0,(x,y)->x+y);//传入两个参数,第一个identity为起始值,第二个指运算方式
System.out.println(sum);
System.out.println("--------------------------");
Optional sum2=employees.stream()//返回值为Optional的原因是没有传入初始的identity,最终结果可能为空
.map(Employee::getSalary)//先映射出salary
.reduce(Double::sum);//只传入一个接口BinaryOperator,sum是1.8版本添加的Double类的静态方法
System.out.println(sum2);
System.out.println("--------------------------");
该方法功能比较强大,能将流收集成很多形式。collect方法接收的多个参数中主要有一个Collector接口,该接口的实现类Collectors提供很多静态方法便于多种形式的收集,比较强大。
(1)List Set HashSet等收集
List l2=employees.stream()
.map(Employee::getName)
.collect(Collectors.toList());
l2.forEach(System.out::println);
System.out.println("--------------------------");
Set set1=employees.stream()
.map(Employee::getName)
.collect(Collectors.toSet());
set1.forEach(System.out::println);
System.out.println("--------------------------");
HashSet hs=employees.stream()
.map(Employee::getName)//特殊的set或者list map收集
.collect(Collectors.toCollection(HashSet::new));
hs.forEach(System.out::println);
System.out.println("--------------------------");
Long count=employees.stream()
.collect(Collectors.counting());
System.out.println("总数:"+count);
System.out.println("--------------------------");
Double ave=employees.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println("平均值:"+ave);
System.out.println("--------------------------");
Double sumSalary=employees.stream()
.collect(Collectors.summingDouble(Employee::getSalary));
System.out.println("总和:"+sumSalary);
System.out.println("--------------------------");
Optional maxSalary=employees.stream() //这里返回的是Optional
.collect(Collectors.maxBy((x,y)->Double.compare(x.getSalary(), y.getSalary())));
System.out.print("最大薪资的员工:");
print(maxSalary.get());
System.out.println("--------------------------");
Optional minSalary=employees.stream()
.map(Employee::getSalary)//
.collect(Collectors.minBy(Double::compare));
System.out.println("最少的工资是:"+minSalary.get());
System.out.println("--------------------------");
Map> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus));
System.out.println(map);
多级分组
Map>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
if(e.getAge() >= 60)
return "老年";
else if(e.getAge() >= 35)
return "中年";
else
return "成年";
})));
System.out.println(map);
Map> map = emps.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
System.out.println(map);