一、介绍
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种 声明的方式 处理集合数据。
使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高阶抽象。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如++筛选, 排序,聚合++等。
二、优点
- 无存储。Stream不是一种数据结构,它只是某个数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
- 为函数式编程而生。对Stream的任何修改都不会修改背后的数据源,比如对Stream执行过滤操作并不会删除过滤的元素,而是会产生一个不包含被过滤元素的新Stream。
- 惰式执行。Stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
-
可消费性。Stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。
如上图,对于流的处理,主要有三种关键性操作:分别是流的创建、中间操作(intermediate operation)以及最终操作(terminal operation)。
三、Stream的创建
- 通过已有集合来创建流
List<String> strings = Arrays.asList("Hollis", "HollisChuang");
Stream<String> stream = strings.stream();
- 通过Stream创建流
Stream<String> stream = Stream.of("Hollis");
四、Stream中间操作
- filter
filter方法用于通过设置的条件过滤出元素。
// 过滤空字符串
List<String> strings = Arrays.asList("Hello","","jade");
strings.stream().filter(s -> !s.isEmpty()).forEach(System.out::print);
- map
map方法用于映射每个元素到对应的结果
//输出
List<Integer> list = Arrays.asList(3,8);
list.stream().map(i -> i*i).forEach(System.out::println);
- limit/skip
limit返回Stream的前面n个元素
skip则是扔掉前n个元素
// 返回前面n个元素
List<Integer> lists = Arrays.asList(3, 8, 8, 3, 112, 2);
lists.stream().limit(3).forEach(System.out::println);
- sorted
sorted方法用于对流进行排序
List<Integer> lists = Arrays.asList(3, 2, 8);
lists.stream().sorted().forEach(System.out::println);
- distinct
去重
List<Integer> numbers = Arrays.asList(3, 2, 2);
numbers.stream().distinct().forEach(System.out::println);
五、Stream最终操作
Stream的中间操作得到的结果也是Stream,因此需要 最终操作 来计算出流中元素的个数、转换成集合等
注意:最终操作会消耗流,产生一个最终结果。
也就是说,在最终操作之后,不能再次使用流,也不能在使用任何中间操作,否则将抛出异常
java.lang.IllegalStateException: stream has already been operated upon or closed
- forEach
Stream提供了方法'forEach'来迭代流中每个数据
//输出随机数
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
- count
// 统计流中元素个数
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis");
System.out.println(strings.stream().count());
- collect
//归约操作:接受各种做法作为参数,将流中元素汇总结果:[Hollis, HollisChuang, Hollis666, Hollis]
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis", "Hollis666", "Hello", "HelloWorld", "Hollis");
strings = strings.stream().filter(string -> string.startsWith("Hollis")).collect(Collectors.toList());
System.out.println(strings);
各流程展示结果
六、总结
本文介绍了Java 8中的Stream 的用途,优点等。还接受了Stream的几种用法,分别是Stream创建、中间操作和最终操作。
Stream的创建有两种方式,分别是通过集合类的stream方法、通过Stream的of方法。
Stream的中间操作可以用来处理Stream,中间操作的输入和输出都是Stream,中间操作可以是过滤、转换、排序等。
Stream的最终操作可以将Stream转成其他形式,如计算出流中元素的个数、将流装换成集合、以及元素的遍历等。