上一篇文章我讲解 Stream 流的基本原理,以及它与集合的区别关系,讲了那么多抽象的,本篇文章我们开始实战,讲解流的各个方法以及各种操作
没有看过上篇文章的可以先点击进去学习一下 简洁又快速地处理集合——Java8 Stream(上),当然你直接看这篇也可以,不过了解其本身才能更融会贯通哦。
值得注意的是:学习 Stream 之前必须先学习 lambda 的相关知识。本文也假设读者已经掌握 lambda 的相关知识。
本篇文章主要内容:
- 流基本的常用方法
- 一种特化形式的流——数值流
- Optional 类
- 如何构建一个流
- collect 方法
- 并行流相关问题
一. 一般方法
首先我们先创建一个 Person 泛型的 List
List<Person> list = new ArrayList<>();
list.add(new Person("jack", 20));
list.add(new Person("mike", 25));
list.add(new Person("tom", 30));
Person 类包含年龄和姓名两个成员变量
private String name;
private int age;
1. stream() / parallelStream()
最常用到的方法,将集合转换为流
List list = new ArrayList();
// return Stream<E>
list.stream();
而 parallelStream() 是并行流方法,能够让数据集执行并行操作,后面会更详细地讲解
2. filter(T -> boolean)
保留 boolean 为 true 的元素
保留年龄为 20 的 person 元素
list = list.stream()
.filter(person -> person.getAge() == 20)
.collect(toList());
打印输出 [Person{name='jack', age=20}]
collect(toList()) 可以把流转换为 List 类型,这个以后会讲解
3. distinct()
去除重复元素,这个方法是通过类的 equals 方法来判断两个元素是否相等的
如例子中的 Person 类,需要先定义好 equals 方法,不然类似[Person{name='jack', age=20}, Person{name='jack', age=20}]
这样的情况是不会处理的
4. sorted() / sorted((T, T) -> int)
如果流中的元素的类实现了 Comparable 接口,即有自己的排序规则,那么可以直接调用 sorted() 方法对元素进行排序,如 Stream
反之, 需要调用 sorted((T, T) -> int)
实现 Comparator 接口
根据年龄大小来比较:
list = list.stream()
.sorted((p1, p2) -> p1.getAge() - p2.getAge())
.collect(toList());
当然这个可以简化为
list = list.stream()
.sorted(Comparator.comparingInt(Person::getAge))
.collect(toList());
5. limit(long n)
返回前 n 个元素
list = list.stream()
.limit(2)
.collect(toList());
打印输出 [Person{name='jack', age=20}, Person{name='mike', age=25}]
6. skip(long n)
去除前 n 个元素
list = list.stream()
.skip(2)
.collect(toList());
打印输出 [Person{name='tom', age=30}]
tips:
- 用在 limit(n) 前面时,先去除前 m 个元素再返回剩余元素的前 n 个元素
- limit(n) 用在 skip(m) 前面时,先返回前 n 个元素再在剩余的 n 个元素中去除 m 个元素
list = list.stream()
.limit(2)
.skip(1)
.collect(toList());
打印输出 [Person{name=