Java--Stream流操作
一、Stream概述
Jdk在1.7之后提供了函数式编程,随之而来的还有Stream流。
通过流可以达成链式操作。
Stream这里的流与IO流毫无关系,这里的流指的是流式操作,就是流水线操作。
Stream流操作主要包包括三大模块:创建流操作、中间流操作、终结流操作。
其中创建流主要是创建Stream对象。每个Stream对象只能使用一次终结操作。
中间流操作指的是各种中间流操作方法,比如去重、过滤、排序等
终结流操作指的结果操作,终结操作的目的是产生最终结果。
二、创建流
Java提供了多种方式创建流。
1、基于数组创建流
Arrays有个静态方法stream可以将数组转换成对应的Stream.
Stream的of方法也是调用它。
int[] a = new int[] { 1, 2, 3, 4 };
IntStream s = Arrays.stream(a);//方法一
Stream<String> s2=Stream.of("h","e","l","l","o");//方法二
s.forEach(System.out::print);//遍历输出
s2.forEach(System.out::print);
2、基于生成器创建流
Stream提供了生成器方法,可用于构建流。
Builder builder= Stream.builder();
Stream<String> stream= builder.add("hello").add("world").build();
stream.forEach(System.out::println);
3、基于集合创建流
集合和数组一样,也可以创建流。
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Stream<Integer> stream=list.stream();
stream.forEach(System.out::println);
4、基于函数创建流
Stream的generate方法接收一个Supplier参数,即一个有返回值的函数,同时通过limit函数控制生成次数。
Stream<String> stream=Stream.generate(()->"hello world").limit(10);//生成10次
stream.forEach(System.out::println);//打印10次hello world
二、中间流
这里的流中间操作指的是该操作的返回值仍然是流。
并且中间流操作需要有终结流结尾。
流操作函数如下:
序号 | 操作 | 方法 | 说明 | 备注 |
---|---|---|---|---|
1 | filter | Stream |
返回当前流中满足参数predicate过滤条件的元素组成的新流 | 过滤器 |
2 | map | 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新流 | 函数 | |
3 | mapToInt | IntStreammapToInt(ToIntFunction<?superT>mapper) | 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Int流 | 函数 |
4 | mapToLong | LongStreammapToLong(ToLongFunction<?superT>mapper) | 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Long流 | 函数 |
5 | mapToDouble | DoubleStreammapToDouble(ToDoubleFunction<?superT>mapper) | 返回通过给定mapper作用于当前流的每个元素之后的结果组成的新的Double流 | 函数 |
6 | flatMap | 根据给定的mapper作用于当前流的每个元素,将结果组成新的流来返回 | 扁平函数 | |
7 | flatMapToInt | IntStreamflatMapToInt(Function<?superT,?extendsIntStream>mapper) | 根据给定的mapper作用于当前流的每个元素,将结果组成新的Int流来返回 | 扁平函数 |
8 | flatMapToLong | LongStreamflatMapToLong(Function<?superT,?extendsLongStream>mapper) | 根据给定的mapper作用于当前流的每个元素,将结果组成新的Long流来返回 | 扁平函数 |
9 | flatMapToDouble | DoubleStreamflatMapToDouble(Function<?superT,?extendsDoubleStream>mapper) | 根据给定的mapper作用于当前流的每个元素,将结果组成新的Double流来返回 | 扁平函数 |
10 | distinct | Stream |
返回去掉当前流中重复元素之后的新流 | 去重 |
11 | sorted | Stream |
返回当前流中元素排序之后的新流,需要元素类型实现Comparable | 排序 |
12 | sorted | Stream |
返回当前流中元素排序之后的新流,需要传递一个Comparator | 排序 |
13 | peek | Stream |
针对流中的每个元素执行操作action | 查阅 |
14 | limit | Stream |
返回指定的数量的元素组成的新流 | 限制 |
15 | skip | Stream |
返回第n个之后的元素组成的新流 | 跳过 |
这些函数用法一样,只是参数和返回值方面有些差异。有些函数其实功能完全 一样,只是名字不同而已,方便区分罢了。
1、filter过滤
filter方法是过滤器方法,针对的是流中所有元素,满足条件的元素将会被保留以组成新的流。
//过滤流
static void filter_o(List<Integer> list){
Stream<Integer> stream= list.stream();
stream.filter(e->e>3).peek(System.out::println).count();
//peek(System.out::println).count()==forEach(System.out::println)
}
// Stream流操作
public static void main(String[] args) {
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(3);
list.add(5);
list.add(7);
filter_o(list);
}
2、peek查阅
peek对流中的每个元素执行一次操作,类似forEach,不过forEach是终结流,peek是中间流。
以上的语句中也可以这样写:
stream.filter(e->e>3).peek(e->System.out.println(e)).count();
通常用于查阅。
3、map映射
map映射函数,用于处理元素。
map方法的参数类型为Function,该函数式接口用于接受一个参数,返回一个结果。
使用同上。
4、distinct去重
distinct方法用于去重
5、limit截取
取到前n个元素
6、sorted排序
对元素排序
。。。。。。。。。
三、终结流
使用终结流之后该流接结束了,不会再返回流。
常用的方法有:
1、forEach循环
接收一个函数,对每个元素执行一次函数,常用于遍历。
2、count计数
返回流中元素的个数。
3、max/min最值
通过给定规则,返回最值。
4、collect归纳
collect用于归纳总结,并返回相应数据集合。
该方法有两个,一个接收三个函数作为参数,一个接收一个collector.
public interface Stream<T> extends BaseStream<T, Stream<T>> {
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);
}
、第一个重载方法,三个参数分别是三个函数,直接使用函数引用即可。
List<Integer> list1=stream.filter(e->e>3)
.peek(e>System.out.println(e))
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
//参数1创建一个集合,参数2指定加入元素的方法,参数3用于并行流
//使用方法引用,也可以使用lambda,如:
()->{ArrayList l=new ArrayList<>();return l;},
(l,e)->{l.add(e);},
(l,e)->{l.addAll(e);}
第二个重载方法,需要传入一个Collector类型的参数,这个Collector是定义来承载一个收集器,但是JDK提供了一个Collectors工具类,可以将流中的元素转换成各种容器。
如:
List<Integer> list1=stream.filter(e->e>3).peek(e->System.out.println(e))
.collect(Collectors.toList());