Fork me on GitHub

Java8 Stream API简介

前言

今天来简单讲下Java8新增的Stream API。

Stream是Java8新增的对于集合框架操作的一个类,我们也称之为流操作。使用Stream,可以简化很多重复代码,使用并行流时有时还能提高程序运行效率。我们来看下。

正文

要把一个集合,List、Set或其他集合类转换为一个流,需要调用stream方法(转换为串行流)或者parallelStream方法(转换为并行流)。

Stream的常用方法如下表格介绍:

常用方法说明参数举例
filter(Predicate<? super T> predicate)过滤,返回一个匹配给定布尔表达式的数据流一个返回值为boolean的lambda表达式例1
map(Function<? super T, ? extends R> mapper)匹配,对流的每个元素都应用给定的函数以获得新流任一符合条件的lambda表达式例2
mapToInt(ToIntFunction<? super T> mapper)将流数据转换为IntStream流流元素转为int的lambda表达式例3
mapToLong(ToLongFunction<? super T> mapper)将流数据转换为LongStream流流元素转为long的lambda表达式
mapToDouble(ToDoubleFunction<? super T> mapper)将流数据转换为DoubleStream流流元素转为Double的lambda表达式
flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)返回一个对流的每个元素都应用给定的函数的新流。这个入参lambda包含有过滤流,此方法类似于平常的双重循环一个包含过滤流的lambda表达式例4
flatMapToInt(Function<? super T, ? extends IntStream> mapper)参考mapToInt参考mapToInt
flatMapToLong(Function<? super T, ? extends LongStream> mapper)参考mapToLong参考mapToLong
flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper)参考mapToDouble参考mapToDouble
distinct()去除流中的重复元素无参数例5
sorted()对流中元素进行排序,使用自然顺序。无参数例6
sorted(Comparator<? super T> comparator)对流中的元素进行排序,按照指定的规则流中元素的比较规则例7
peek(Consumer<? super T> action)截断流后进行某些操作指定的操作,无返回值lambda例8
limit(long maxSize)获取流中的前n个元素的流限定值例9
skip(long n)获取从n开始后面元素的流,不包括n,如果n超出流长度,返回一个空流起始长度例10
forEach(Consumer<? super T> action)循环流中的每个元素,执行指定的lambda表达式无返回值的lambda表达式例11
forEachOrdered(Consumer<? super T> action)按照默认顺序循环流中的元素,执行指定的lambda表达式无返回值的lambda表达式
toArray()返回流中元素组成的数组无参数例12
toArray(IntFunction<A[]> generator)将流中元素转换为指定类型的数组,数组类型必须是流元素的本身或者超类
reduce(T identity, BinaryOperator<T> accumulator)归约,将流中的元素按照指定表达式归并。起始值(默认值),指定归约公式例13
reduce(BinaryOperator<T> accumulator)同上,不同的是这个没有设置起始值,故结果可能为空,返回的是Optional对象指定的归约公式
reduce(U identity,BiFunction<U,? super T,U> accumulator,BinaryOperator<U> combiner)归约全参方法,可以指定初始值,归约方法,归约方式例14
collect(Collector<? super T, A, R> collector)收集器,比较常用的是toList,将流元素变为集合
collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner)收集器,可以指定收集规则,收集方法等
min(Comparator<? super T> comparator)根据指定规则获取流中最小值排序规则lambda表达式例15
max(Comparator<? super T> comparator)根据指定规则获取流中最大值排序规则lambda表达式例15
count()统计流中元素数量无参数例16
anyMatch(Predicate<? super T> predicate)查找流中是否有元素符合条件,一旦查到,就返回true条件的lambda表达式例17
allMatch(Predicate<? super T> predicate)查找流中的元素是否全部匹配指定表达式,全部符合才返回true条件的lambda表达式例18
noneMatch(Predicate<? super T> predicate)查找流中的元素是否全部不匹配指定表达式,全部不匹配才返回true条件的lambda表达式
findFirst()查找流的第一个元素,如果流为空,返回空(Optional的空)无参数
findAny()随便从流中拿一个元素,如果流为空,返回空(Optional的空)无参数
empty()静态方法,返回一个空流例19
of(T t)静态方法,生成一个元素的流例19
of(T… values)静态方法,生成若干元素的流例19
iterate(final T seed, final UnaryOperator<T> f)静态方法,生成一个有规律的流起始值,指定的lambda表达式例19
generate(Supplier<T> s)静态方法,生成指定规则的数据流,流数据的生成完全取决于lambda表达式生成流数据的lambda表达式例19
concat(Stream<? extends T> a, Stream<? extends T> b)静态方法,将两个数据流合并,两个流的类型须一致两个数据流例19

例子

举例:假设有一个1-100的List集合list1,50-150的List集合list2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//例1:需要一个1-100的偶数List集合。
list1.stream().filter(n->n%2==0).collect(Collectors.toList());
//例2:获取list1各元素加上100,再取基数的List集合。
list1.stream().map(n->n+100).map(n->n%2!=0).collect(Collectors.toList());
//例3:将list1的流转换为IntStream。
list1.stream().mapToInt(n->n.intValue());
//例4:list1和list2的交集集合。
list1.stream().flatMap(i->list2.stream().map(j->i==j)).collect(Collectors.toList());
//例5:list1和list2的并集集合。
list1.addAll(list2);
list1.stream().distinct();
//例6:对list1进行排序。
list1.stream().sorted().collect(Collectors.toList());
//例7:对list1进行倒序排序。
list1.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
//例8:截断查看流的每一步得到的流元素。
list1.stream().map(n->n+100).peek(System.out::println).map(n->n%2!=0).peek(System.out::println).collect(Collectors.toList());
//例9:取list1的前10个元素。
list1.stream().limit(10).collect(Collectors.toList());
//例10:取list1的后10个元素。
list1.stream().skip(list1.size()-10).collect(Collectors.toList());
//例11:输出list1的各个元素。
list1.stream().forEach(System.out::println);
//例12:将list1元素转为数组。
list1.stream().toArray();
//例13:对list1元素求和,对list2元素求差。
list1.stream().reduce(0,(a,b)->a+b);
list2.stream().reduce(0,(a,b)->a-b);
//例14:对list1按照最大值到最小值求和。
list1.stream().reduce(0,(a,b)->a+b, BinaryOperator.maxBy(Comparator.naturalOrder()));
//例15:取list1的最大最小值
list1.stream().max(Comparator.naturalOrder());
list1.stream().min(Comparator.naturalOrder());
//例16:求list1的元素个数
list1.stream().count();
//例17:查询list1中有没有17的倍数(除了17)。
list1.stream().anyMatch(n->n!=17&&n%17==0);
//例18:查询list1中所有元素是不是都是2的倍数。
list1.stream().allMatch(n->n%2==0);
//例19:
Stream.empty();//空流
Stream.of(1);//生成一个元素的流
Stream.of(1,2,3,4);//生成若干元素的流
Stream.iterate(1,n->2*n);//生成指定规则的数据流
Stream.generate(()->Math.random());//生成指定规则的数据流
Stream.concat(list1.stream(),list2.stream());//将两个数据流合并

结语

Java8 Stream API的一些常用方法基本如上,Stream API为操作集合类提供了更方便快捷的方式,值得我们掌握。




-------------文章结束啦 ~\(≧▽≦)/~ 感谢您的阅读-------------

SakuraTears wechat
扫一扫关注我的公众号
您的支持就是我创作的动力!
0%