综述
stream流提供可以以一种声明的方式处理数据,是一个来自数据源的元素队列并支持聚合操作。
- 原元素是特定类型的对象,形成一个队列。stream并不会存储元素,而是按需计算。
- 数据源 也即是流的来源,可以是集合、数组、IO/channel等。
- 聚合操作,如filter, map, reduce, find, match, sorted等。
要得到一个stream通常不会手动创建,而是调用已存在的方法如:
Collection.stream()
Collection.parallelStream()
Arrays.stream(T[] array)
stream接口继承关系如下图:
4中stream继承自一个BaseStream,intStream、LongStream和DoubleStream分别对应基本数据类型的int、long、double,其余的所有类型对应Stream。
既然这四种类型方法基本一致,那为什么不把前三个继承自Stream如下图这样设计呢?
这是因为这四种类型方法名称虽然相同,但是返回类型去不一致,在Java中是不允许只有返回类型不一致的方法重载。
stream与Collections的区别
- stream无存储,它只是某种数据源的一种视图,也就是说stream不是一种数据结构;
- 为函数式编程而生,也就是说对stream的任何操作都不会改变数据源本身,比如对数据源的过滤操作并不会删除不符合条件的元素,而是生成一个新的只包含符合条件的元素;
- 惰性执行,stream并不会立即执行,而是在真正需要的时候再执行;
- 可消费性,stream只能被消费一次,一旦被遍历过就会失效,像for循环那样。
stream的操作分为两类:中间操作和结束操作
- 中间操作:惰性执行,只会生成一个新的stream流;
- 结束操作:会触发实际计算,计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。
操作类型 | 接口方法 |
---|---|
中间操作 | concat() distinct() filter() flatMap() limit() map() peek() skip() sorted() parallel() sequential() unordered()等 |
结束操作 | allMatch() anyMatch() collect() count() findAny() findFirst() forEach() forEachOrdered() max() min() noneMatch() reduce() toArray()等 |
1、stream的简单使用学习
- forEach,Stream 提供了新的方法 ‘forEach’ 来迭代流中的每个数据,利用forEach打印
List<String> forEachList = Arrays.asList("a","b","c","d");
forEachList.stream().forEach(string -> System.out.println(string));
- filter(),根据条件进行过滤
获取长度小于等于3的字符串
List<String> filterList = Arrays.asList("I am","a","student","now");
List<String> filterListRes = filterList.stream().filter(string -> string.length() <= 3).collect(Collectors.toList());
System.out.println(filterListRes);
- distinct(),去重
- sorted,排序
排序函数有两个,一个是使用自然顺序排序,另一个就是使用自定义的Comparator排序 - map(),简单来说就是对每个元素按照某种操作进行转换
将list转换为大写
List<String> mapList = Arrays.asList("I am","a","student","now");
List<String> resMapList = mapList.stream().map(string -> string.toUpperCase()).collect(Collectors.toList());
System.out.println(resMapList);
- limit(),用于获取指定数量的流
- parallelStream,流并行处理程序的代替方法
- 统计
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());