为什么使用Stream流
减少数据库的访问,在内存中操作,执行效率更快
stream中提供了一套api,封装了的对集合(List)的数据的各种操作
循环遍历弊端
对集合中的元素进行操作的时候,需要进行循环,再循环,操作步骤比较繁琐,如果此类操作的过多,容易造成代码的重复度高
Stream流
1.元素序列
可以支持函数式编程
集合讲的是数据存储,流讲的是计算
2.源
流使用一个提供数据的源
3.数据处理操作
使用Stream中的api
Stream流的对象创建
1.对list集合,掌握
list.stream()
2.Arrays集合
Arrays.stream();
3.stream流,掌握
Stream.of();
4.stream流
Stream.iterate()
5.stream流
Stream.generate()
Stream提供的API
筛选和切片
filter((Predicate p):过滤
distinct:去重
limit(long n):限定保留数据的个数
skip(long n):跳过n个数据
映射
1.map(Function <T,R> f),将一个元素映射为另一个元素
2.flatMap(Function<T, Stream> mapper),将两个流合并成一个流
排序
comparater是比较器
1.sorted():这是默认的升序,从小到大
2.sorted(Comparator.reverseOrder():自定义排序规则,降序
3.sorted((o1, o2) -> o2-o1):通过改变表达式后边的顺序改变排序规则
查找匹配
里面的结果都是true/false
allMatch:检查是否匹配所有元素
anyMatch:坚持是否至少匹配一个元素
noneMatch:检查是否没有匹配的元素
findFirst:返回第一个元素,返回值类型是Optional
findAny:用于并行流,返回流中的任意一个元素,返回值类型是Optional
示例:
Stream.of(12, 35, 45, 56)
.allMatch(num -> num % 2 == 0)
Optional的作用:
防止出现NullpointException,里面有以下方法可以使用:
Optional<Integer> first = Stream.of(12, 35, 45, 56).findAny();
isPresent():判断容器中是否有值
first.isPresent()
ifPresent(Consume lambda):不为空就执行Lambda表达式
first.ifPresent(x-> System.out.println(x));
get:获取容器中的元素
first.get()
统计
**count()😗*返回流中元素的个数
**max(Comparator)😗*返回流中的最大值,里面需要进行比较大小,得到的是最大的索引,使用get方法取出值
Optional<Integer> max = Stream.of(12, 35, 45, 56).max((a, b) -> a-b);
System.out.println(max.get());
**min(Comparator)😗*取出流中最小值
归约
对元素进行加减乘除的到一个值
reduce(1, (x, y) -> x * y):1表示起始值,后面的是计算过程
汇总
**collect()😗*从Stream中生成一个集合或者Map等复杂的对象
1.stream->ArrayList集合
list.stream().collect(Collectors.toList());
2.stream->HashSet集合
list.stream().collect(Collectors.toSet());
3.stream->TreeSet集合,其他类型也是这样写,自己指定类型的集合
list.stream().collect(Collectors.toCollection(TreeSet::new));
4.Stream->sum,使用方法summarizingInt
IntSummaryStatistics collect = list.stream()
.collect(Collectors.summarizingInt(Integer::new));
System.out.println(collect.getSum());
5.Stream->Max
6.Stream->Min
7.Stream->count
分组和分区
Collectors.groupingBy():会根据条件对元素分组
Map<String,List<Product>> map= products.stream()
.collect(Collectors.groupingBy(p->p.getName()));
System.out.println(map);
Collectors.partitioningBy():根据条件得到的boolean类型分成两个区
并行和并发
并行:同一时间点执行多个任务,单核
并发,同一时间段执行多个任务,多核,利用cpu的空闲时间,多线程
并行流的特点
利用多核的空间提高执行的操作效率
将顺序流转化为并行流
方式一
list.stream().parallel()
方式二,省略转化成Stream流的步骤
list.parallelStream()
影响并行流性能的主要因素
1.数据大小
在数据量过大的时候会体现出并行流的性能
2.处理集合类型的数据结构
3.cpu核的数量
4.花费在流中每个元素的时间越长越明显