title: 初识STREAM
date: 2020-11-26 13:18:38
tags: java
概述
Stream流一般分为三个步骤:
- 创建stream流,可以从集合或数组中获取流
- 流的中间操作,可以对流进行筛选,跳过等数据操作
- 流的终止,可以将其收集为数组或获取到某种数据
接下来从以上三个方面阐述stream的编码过程。
创建stream流
可以从数组中获取流,或根据数组创建流,常见的创建方式有:
//从list获取
Stream <String> s1 = Arrays.asList("a","b","c").stream();
//直接创建
Stream <String> s2 = Arrays.stream("a","b","c");
Stream <String> s3 = Stream.of("a","b","c");
流的中间操作
流的中间操作会返回一个操作结果后的流,同时其形式像这样:
stream = stream.operator();
常见的流中间操作有:
filter当返回值为true时保留该流对象,为false则过滤该对象。例如筛选年龄大于20岁的学生:
Stream <Student> stream = stream.filter((e)->{
return e.getAge()>=20;
} ); //e的数据类型为<XXX>定义的数据类型,这里e是Student类的
skip(n),跳过前n个元素
stream = stream.skip(1); //跳过第一个元素
distinct(),根据equals()和hashcode()进行去重
stream = stream.distinct(); //去除重复元素
sorted(Comparator),根据选择器排序
stream = stream.sorted(); //自然语序排序
stream = stream.sorted((o1,o2)->{
return o1.getAge() - o2.getAge();
}) //使用lambda语句进行排序
stream = stream.sorted(new Comparator<Student>(){
@Override
public int compare(Student s1,Student s2){
return s1.getAge() - s2.getAge();
}
}); //使用自定义的Comparator进行排序
map(),flatMap()均是将每一个流对象进行操作,map返回流本身,flatMap返回操作结果的流额外进行了flat的合并处理,为此要求了flatMap的函数返回值必须是List或stream,不然无法进行flat处理。
//定义一个小写转大写的函数
public static Stream <Charactor> upper(String str){};
Stream <String> streams = Stream.of("a","bbb","cc"); //将三个字符串看成三个流对象
Stream <Stream <Charactor> >streams2 = streams.map(e->upper(e)); //对每个流对象处理得到一个流,所以运行结果是一个含三个流的流对象
Stream <Charactor> stream3 = streams.flatMap(MAIN::upper); //这里同样得到三个流后对流进行了合并flat操作,所以结果是一个只含有字符的流对象
终止操作
终止操作分为两种,查询和收集。查询指最终结果是某一种数据形式,如查询所有人年龄的最大值,查询名字中含“a”的人的姓名。收集指结果是数组形式,是包含多个数据对象的结果。
查询操作
查询操作有allMatch,anyMatch,findFirst,max,min等操作类型,例如:
boolean result1 = stream.allMatch(e->e.getName().length()>=2); //判断所有人的姓名长度是否都大于2
boolean result2 = stream.anyMatch(e->e.getAge() >=30); //判断是否有人年龄大于30
Optional <Student> first = stream.findFirst(); //使用Optional接住查询结果
Systeam.out.println(first.get()); //使用get()方法取得在Optional里的Student对象
Optional <Integer> maxAge = stream.max((o1,o2)->{ //max里面使用lambda写好Comparator
return o1.getAge() - o2.getAge();
}); // 同样使用Optional接住查询结果
System.out.println(maxAge.get()); //打印get到的Integer对象
收集操作
收集操作一般使用一个Collertor存储stream流的处理结果,如list/set/map,也可以使用.collect(Collectors.XXX())的方法来取得想要的结果。
List <String> list = stream.map(e-> e.getName()).collect(Collectors.toList()); //使用toList将stream存储到list中
Map <String,Integer> map = stream.collect(Collectors.toMap(e->e.getName(),e2->e2.getAge())); //使用toMap将stream存储到map中
Optional <Student> max2 = stream.collect(Collectors.maxBy((a1,a2)-> a1.getAge()-a2.getAge())); //使用get就可以获取到年龄最大的Student对象