原文链接:https://www.longkui.site/program/java/java-stream/6440/
0.stream流
Java8API添加了一个新的抽象称为流Stream,将要处理的元素集合看作一种流, 流在管道中传输,能够对每个元素进行一系列并行或串行的流水线操作。
1.常用方法
我们创建实体类:
public class Students{
String name; //姓名
Integer age; //年龄
Double math; //数学成绩
Double chinese; //语文成绩
String birthday; //生日
}
假设生成的数据如下:
(1)filter(element -> boolean表达式)
作用:过滤元素,符合Boolean表达式的留下来
例子1:
List<Students> data= studentsList.stream().filter(s->s.getMath()>90).collect(Collectors.toList());
我们也可以多次筛选,比如除了上面的条件,我们再加入筛选判断大于等于18岁的人。
List<Students> data= studentsList.stream().filter(s->s.getMath()>90).filter(x->x.getAge()>=18).collect(Collectors.toList());
(2)distinct 去重
distinct使用了hashCode()和equals()方法来获取不同元素。
基础用法:
studentsList.stream().distinct().collect(Collectors.toList())
上面这个用法可以整体进行去重。
如何需要根据某个字段进行去重?我们可以使用collectingAndThen
List data= studentsList.stream().collect(
Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Students::getAge))), ArrayList::new
));
上面的结论可以看到,我们根据age这个属性进行了去重。
(3)sort 排序
假如我们要根据数学成绩进行排序
List data= studentsList.stream()
.sorted(Comparator.comparingDouble(Students::getMath))
.collect(Collectors.toList());
comparingDouble是比较的Double类型,如果需要可以改成comparingInt类型。
(4)limit 返回前n个元素
List data= studentsList.stream()
.limit(1)
.collect(Collectors.toList());
(5)skip 去除前n个元素
去除前n个元素
limit(m).skip(n),先返回前m个元素,再从这m个元素中去除n个
skip(n).limit(m),先去除n个元素,再返回剩余的前m个
可以看出,去除了前1个,剩余了三个。
(6)map
map作用就是针对管道流中的每一个数据元素进行转换操作。
假如我们需要修改每个人的数学成绩,将数学成绩翻倍
List data= studentsList.stream()
.map(x->{
x.setMath(x.getMath()*2);
return x;
})
.collect(Collectors.toList());
我们也可以把数据按照某个属性组成一个新的集合。
List data= studentsList.stream()
.map(Students::getName)
.collect(Collectors.toList());
(7)anyMatch
判断流中是否有元素满足这个Boolean表达式
boolean flag=false;
flag = studentsList.stream().anyMatch(x -> x.getAge() == 18);
(8)allMatch
allMatch(T -> boolean)即流中所有元素是否都满足Boolean条件
noneMatch(T -> boolean)即是否流中没有一个元素满足Boolean表达
(9)count()
返回流中元素的个数,返回Long型
(10)reduce
reduce操作将二进制运算符应用于流中的每个元素,其中运算符的第一个参数是前一个应用程序的返回值,第二个参数是当前流元素。
一共有三种用法:
Optional reduce(BinaryOperator accumulator);
T reduce(T identity, BinaryOperator accumulator);
U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator combiner)
例子:
int sum1 = studentsList.stream().map(Students::getAge).reduce(0, (a, b) -> a + b); //求和
int sum2 = studentsList.stream().map(Students::getAge).reduce(0, Integer::sum); //求和
Double max=studentsList.stream().map(Students::getMath).reduce(studentsList.get(0).getMath(), Double::max); //求数学的最大值
Double min=studentsList.stream().map(Students::getMath).reduce(studentsList.get(0).getMath(), Double::min); //求数学的最小值
(11)forEach
处理集合时不能使用break和continue中止循环
可以使用关键字return跳出本次循环,并执行下一次遍历
不能跳出整个流的forEach循环
studentsList.stream().forEach((x)->{
System.out.println(x.getName());
}
);
2.Collect收集方法
收集流中元素的方法,传参是一个收集器接口, 常用写法:
.collect(Collectors.toList())收集到list集合
.collect(Collectors.toMap(x,x,x))收集到map集合
.collect(Collectors.groupingBy(xx))分组
.collect(Collectors.counting())统计集合总数
.collect(joining())连接字符串