
介绍常用的StreamAPI。
本文中的例子GitHub地址:https://github.com/Lee875083146/java8/blob/master/src/main/java/com/nopainanymore/java8/Stream/StreamOperation.java
例子中使用的类:
|
函数原型为<R, A> R collect(Collector<? super T, A, R> collector);,使用Collector作为参数,一般使用Collectors类实现的各种收集操作,例如toList,toSet等。Collectors类中还实现了一些有意思的静态方法例如groupingBy,partitioningBy等。
filter()
函数原型为Stream<T> filter(Predicate<? super T> predicate);,其作用是返回满足predicate元素的Stream。
例子:
private static void filter(List<Student> studentList) { |
执行结果:
23:55:33.560 [main] INFO com.nopainanymore.java8.Stream.StreamOperation - StreamOperation- filter- before :[{"name":"a1","age":21,"sex":"女","stuId":1401},{"name":"a2","age":20,"sex":"男","stuId":1402},{"name":"a3","age":21,"sex":"女","stuId":1403},{"name":"a4","age":20,"sex":"男","stuId":1404}] |
使用filter达到了将性别为女的学生过滤。
map()
函数原型为<R> Stream<R> map(Function<? super T, ? extends R> mapper);,其作用返回当前所有元素执行mapper之后的结果组成的Stream。
例子:
private static void map(List<Student> studentList) { |
执行结果:
12:15:24.636 [main] INFO com.nopainanymore.java8.Stream.StreamOperation - StreamOperation- map- before:[{"name":"a1","age":21,"sex":"女","stuId":1401},{"name":"a2","age":20,"sex":"男","stuId":1402},{"name":"a3","age":21,"sex":"女","stuId":1403},{"name":"a4","age":20,"sex":"男","stuId":1404}] |
通过map获取到了所有学生的姓名
mapToInt(), mapToDouble(), mapToLong()
三者的函数原型分别为IntStream mapToInt(ToIntFunction<? super T> mapper);,DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);,LongStream mapToLong(ToLongFunction<? super T> mapper);,分别返回IntStream、DoubleStream、LongStream三种基本类型流,基本类型流可以使用特殊的lambda表达式,同时支持一些聚合方法,如:sum(),average()等。
例子:
private static void mapToInt(List<Student> studentList) { |
执行结果:
12:25:25.829 [main] INFO com.nopainanymore.java8.Stream.StreamOperation - StreamOperation- mapToInt- before:[{"name":"a1","age":21,"sex":"女","stuId":1401},{"name":"a2","age":20,"sex":"男","stuId":1402},{"name":"a3","age":21,"sex":"女","stuId":1403},{"name":"a4","age":20,"sex":"男","stuId":1404}] |
使用mapToInte()将Student流转化为年龄的IntStream,使用average() 获取OptionalDouble类型的结果,求出了学生的平均年龄.
flatMap()
函数原型为<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);,flatMap可以将一个stream中的每一个元素对象转换为另一个stream中的另一种元素对象,因此可以将stream中的每个对象改造成零,一个或多个。flatMap操作的返回流包含这些改造后的对象。
例子:
private static void flatMap(List<List<Student>> classList) { |
执行结果:
12:49:49.925 [main] INFO com.nopainanymore.java8.Stream.StreamOperation - StreamOperation- flatMap- before:[[{"name":"a1","age":21,"sex":"女","stuId":1401,"classId":1},{"name":"a2","age":20,"sex":"男","stuId":1402,"classId":1},{"name":"a3","age":21,"sex":"女","stuId":1403,"classId":1},{"name":"a4","age":20,"sex":"男","stuId":1404,"classId":1}],[{"name":"a1","age":21,"sex":"女","stuId":1401,"classId":2},{"name":"a2","age":20,"sex":"男","stuId":1402,"classId":2},{"name":"a3","age":21,"sex":"女","stuId":1403,"classId":2},{"name":"a4","age":20,"sex":"男","stuId":1404,"classId":2}]] |
通过flatMap将两个List<Student>组成的classList转化为一个List<Student>。
peek()
函数原型Stream<T> peek(Consumer<? super T> action);,返回包含流中所有元素的流并为流中所以元素执行所提供的操作,该方法存在的目的是debug,可以用此方法
例子:
private static void peek(List<Student> studentList) { |
结果:
19:45:58.814 [main] INFO com.nopainanymore.java8.Stream.StreamOperation - StreamOperation- peek- before:[{"name":"a1","age":21,"sex":"女","stuId":1401,"classId":1},{"name":"a2","age":20,"sex":"男","stuId":1402,"classId":1},{"name":"a3","age":21,"sex":"女","stuId":1403,"classId":1},{"name":"a4","age":20,"sex":"男","stuId":1404,"classId":1}] |
由日志打印出的信息我们也可以看到流构成的函数管道,将所有中间操作全部融合后执行。
例子中也使用了count()来统计性别是男的学生人数。
distinct()
函数原型Stream<T> distinct();,返回由该流中equals决定的唯一的元素组成的流,即用来去重。
例子:
private static void distinct(List<Student> studentList) { |
执行结果:
20:14:59.964 [main] INFO com.nopainanymore.java8.Stream.StreamOperation - StreamOperation- distinct- before :[{"name":"a1","age":21,"sex":"女","stuId":1401,"classId":1},{"name":"a2","age":20,"sex":"男","stuId":1402,"classId":1},{"name":"a3","age":21,"sex":"女","stuId":1403,"classId":1},{"name":"a4","age":20,"sex":"男","stuId":1404,"classId":1},{"name":"a1","age":21,"sex":"女","stuId":1401,"classId":2},{"name":"a2","age":20,"sex":"男","stuId":1402,"classId":2},{"name":"a3","age":21,"sex":"女","stuId":1403,"classId":2},{"name":"a4","age":20,"sex":"男","stuId":1404,"classId":2}] |
通过map方法获取classId的集合,通过distinct去重获得不重复的班级。
sorted(comparator)
函数原型Stream<T> sorted(Comparator<? super T> comparator);,返回一个由comparator决定的排序之后的流。
例子:
private static void sorted(List<Student> studentList) { |
执行结果:
20:38:52.395 [main] INFO com.nopainanymore.java8.Stream.StreamOperation - StreamOperation- sorted- before:[{"name":"a1","age":21,"sex":"女","stuId":1401,"classId":1},{"name":"a2","age":20,"sex":"男","stuId":1402,"classId":1},{"name":"a3","age":21,"sex":"女","stuId":1403,"classId":1},{"name":"a4","age":20,"sex":"男","stuId":1404,"classId":1}] |
传入比较学号的lambda表达式,为了逆序用后一个学号减去前一个学号。
limit()
函数原型Stream<T> limit(long maxSize);,截取流中前maxSize组成的元素组成新的流。
private static void limit(List<Student> studentList) { |
执行结果:
20:40:22.430 [main] INFO com.nopainanymore.java8.Stream.StreamOperation - StreamOperation- limit- before:[{"name":"a1","age":21,"sex":"女","stuId":1401,"classId":1},{"name":"a2","age":20,"sex":"男","stuId":1402,"classId":1},{"name":"a3","age":21,"sex":"女","stuId":1403,"classId":1},{"name":"a4","age":20,"sex":"男","stuId":1404,"classId":1}] |
截取了前两个学生。
其他API
Stream中还有很多API在用到时,直接看源码及源码注释即可。
参考资料
Java 8 中的 Streams API 详解
Java 8 Stream 教程
函数纯度
Java 8 Stream探秘
JavaLambdaInternals




近期评论