什么是Stream流?
Stream流,是JDK1.8中对集合对象功能的增强,可以通过将集合转换为流模型,通过声明的方式对集合中个每个元素进行一系列并行或者串行的流水线操作。
它针对于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作。
Stream不是集合元素,不是数据结构并不保存数据,Stream是有关算法和计算的,像是一个高级版本的迭代器Iterator。
Stream只要给出对其包含的元素执行什么操作,Stream就会隐式地在内部进行遍历,并给出响应的数据转换。单向不可往复、数据只能遍历一次,遍历过后就使用完毕。
Stream可以并行化操作,Stream的并行操作是依赖Java7中引入的Fork/Join框架拆分任务和加速处理过程,并且允许数据源是无限的。
基本的执行流程
使用Stream通常包括3个基本步骤:
1、获取一个数据源source
2、转换为流—执行操作
3、获取所想要的结果。
每次转换原有的Stream对象,执行结果还是Stream,可以使用串式写法定义多个操作数据源就是原始的数据集合将 List 集合转换为 Stream。
针对Stream进行一系列操作,每次操作结束返回还是Stream可以将Stream转换回集合类型,也可以直接对其中的元素进行处理:
1、创建Stream
2、转换Stream,每次执行转换Stream对象类型不改变,返回一个新的Stream对象
3、对Stream进行聚合操作,获取想要的结果、
遍历操作
//输出随机数的前十个值
Random r = new Random();
r.ints().limit(10).forEach(System.out::println);
流的转换操作
Stream的操作符基本可以分为中间操作符和终止操作符两大类,中间操作符会继续向下传递,终止操作符直接对数据进行消费或者收集,不会继续向下传递
中间操作符
map转换操作符,可以将一个A转换为一个B
flatMap可以将一个A转换为多个B
limit限流操作
distinct去重操作,底层采用equals进行比对
filter过滤操作,去除不满足条件的数据
peek跳出操作
skip跳过操作
sorted排序操作,Comparable和Comparator接口
终止操作
collect收集操作,使用官方的Collectors提供的收集器
count统计操作,统计数据个数
findFirst/findAny查找操作,返回的类型为Optional
noneMatch、AllMatch和anyMatch匹配操作,检查数据流中是否存在符合条件的数据
min和max最值操作,需要比较器
reduce规约操作,将数据流的值规约为一个值,例如count/min/max底层实际上就是使用reduce
forEach遍历操作,可以对最终的数据进行消费
toArray数组操作,用于将数据流的元素转换为数组
filter方法
filter方法用于对传入的数据流进行过滤处理,只返回满足条件的数据组成的新的数据流。
List<Integer> list = new ArrayList<>();
list.add(111);
list.add(222);
list.add(333);
System.out.println(list);
List<Integer> result = list.stream().filter(i -> i > 50).collect(Collectors.toList());
System.out.println(result);
map方法
map方法用于对流中的数据进行某种形式的转换,转换操作函数当作参数传入方法
例如将Integer转换为String
List<Integer> list = new ArrayList<>();
list.add(111);
list.add(222);
list.add(333);
List<String> result=list.stream().map(i->String.valueOf(i))
.collect(Collectors.toList());
List<String> result = list.stream().map(i -> String.valueOf(i))
.filter(bb->bb.length()>2).collect(Collectors.toList());
flatMap方法
flatMap可以对每个元素应用一个函数,并将返回的值收集到一个新的流中
List<Integer> list=new ArrayList<>();
list1.add(1);
list1.add(2);
List<Integer> list2=new ArrayList<>();
list2.add(33);
list2.add(44);
Map<String,List<Integer>> testMap=new HashMap<>();
testMap.put("aa",list1);
testMap.put("bb",list2);
List<Integer> result=testMap.values() //获取到两个Collection<List<Integer>>
.stream().flatMap(num->num.stream()).collect(Collectors.toList());
limit方法
limit方法会返回一个包含指定个数元素的新stream,如果原始数据总长大小不足则返回原始流
List<Integer> list=new ArrayList<>();
for(int i=0;i<10;i++)
list.add(i);
List<Integer> result=list.stream().limit(5).collect(Collectors.toList());
skip方法
skip方法的含义是跳过多少个元素,继续处理后续元素
List<Integer> list=new ArrayList<>();
for(int i=0;i<10;i++)
list.add(i);
List<Integer> result=list.stream().skip(5).collect(Collectors.toList());
distinct方法
distinct会根据原始流中的元素返回一个具有相同顺序,但是剔除了重复值的流
List<Integer> list=new ArrayList<>();
list.add(54);
list.add(21);
list.add(47);
list.add(32);
list.add(11);
list.stream().forEach(obj -> System.out.print(obj + "\t"));
System.out.println("");
List<Integer> result=list.stream().distinct().collect(Collectors.toList());
System.out.println(result);