Stream流
- 什么是Stream:Stream是对集合对象功能的增强,主要用于对集合对象进行高效的聚合操作,或者进行大批量的数据操作。Stream主要
借助Lambda表达式实现,同时也提供串行和并行进行汇聚操作。并发模式能够充分利用处理器的优势,使用fork/join并行方式来拆分任务
和加速处理过程。使用stream可以不用写一行多线程的代码,就可以实现高性能的并发程序,所以在foreach中不要进行return,也要对变量
进行并发控制。 - 什么是流:流就如果一个迭代器遍历过一次之后、流就用尽了。不同的是、Stream可以并行化操作。
一、stream总览
- 流的构成
获取数据源->数据转换->执行操作获取想要的结果。每次进行数据转换,原有的Stream不改变、返回一个新的Stream对象,这样就可以进行链式的操作。 - 生成Stream source的方式
- Collection.stream()
- Collection.parallelStream()
- Arrays.stream(T array) or Stream.of()
- java.io.BufferedReader.lines()
- java.util.Spliterator
- 流的操作类型
- Intermediate:一个流后面可以跟0个或者多个中间操作,对数据进行过滤,然后返回一个新的流。
- Terminal:一个流只能有一个终端操作,当执行这个操作之后,流就被用光了。
二、Stream Api
-
map/flatmap:将输入的值转成另一种形式例如
Stream.of(map).map(value->value.get("1").toString()).collect(Collectors.toList());
将map中的值转成list,简单来说就是对流中的值进行转换。map是1对1的 flatmap是1对多的`
Stream<List<Integer>> inputStream = Stream.of( Arrays.asList(1), Arrays.asList(2, 3), Arrays.asList(4, 5, 6) ); Stream<Integer> outputStream = inputStream. flatMap((childList) -> childList.stream());
`
这里输出[1,2,3,4,5,6] -
filter: 对流进行过滤,形成一个新的流
Stream.of(arr).filter(a -> a > 1).map(Object::toString).collect(Collectors.toList());
-
forEach:接收一个 Lambda 表达式,进行遍历。
list.forEach(System.out::println);
-
peek:功能类似于foreach,区别在于foreach只能执行一次,peek可以执行多次
-
findfirst:返回stream流中的第一个元素
list.stream().findFirst().orElse(""); //orelse 如果optional中的一个方法,如果optional中值为空就返回值传入的值
-
reduce:作用就是将stream流中的元素组合起来,用来实现sum、min、max或者求平均值
`
1.求和 list.stream().reduce(0,(a,b)->a+b); 2字符串拼接 list.stream().reduce("",String::concat);
`
-
limit/skip:返回前面几个元素或者丢弃前面几个元素
`
1.limit list.stream().limit(1).collect(Collectors.toList()); 2.skip list.stream().skip(1).collect(Collectors.toList());
`
-
sorted:排序,和普通数组排序更强之处在于 可以先对stream进行各类map、filter、limit甚至
distinct减少数量后在排序Integer[] nums = new Integer[]{2,3,1,4,7,6}; Arrays.stream(nums).sorted((l1, l2) -> l2.compareTo(l1)).limit(4) .forEach(System.out::print);
-
min/max/distinct
Integer[] nums = new Integer[]{1, 2, 2, 3, 4, 5, 5, 6}; System.out.println(Arrays.stream(nums).min(Comparator.naturalOrder()).get());//获取最小值 System.out.println(Arrays.stream(nums).max(Comparator.naturalOrder()).get());//获取最大值 Arrays.stream(nums).distinct().forEach(System.out::print);//去重
-
groupingby/partitioningby 分组
final Collection<Student> students = Arrays.asList( new Student(1, Grade.FIRST, 60), new Student(2, Grade.SECOND, 80), new Student(3, Grade.FIRST, 100)); students.stream().collect(Collectors.groupingBy(Student::getGrade)) .forEach(((grade, students1) -> { System.out.println(grade); students1.forEach(student -> System.out.println(student.getId()+","+student.getGrade()+","+student.getScore()));})); } 对年级进行分组 students.stream().collect(Collectors.partitioningBy(student -> student.getScore() <=60)) .forEach(((grade, students1) -> { System.out.println(grade); students1.forEach( student -> System.out.println(student.getId()+","+student.getGrade()+","+student.getScore())); })); 对分数段进行分组
-
parallelStream 并行执行的流
Arrays.stream(nums).parallel().forEach(System.out::print);