Stream的作用
- 简化代码,不易出错
- 可读性/可维护性++
什么是“流”
- 元素一个个地被丢入流中
Stream API: 创建Stream
- Collection.stream()
- Stream.of()
- String.chars()
- IntStream.range()
```java
List
users = getUsers();
// 找出所有姓王的用户,获取名字列表,按年龄排序 users.stream() .filter(user -> user.name.startWith(“王”)) .sorted(comparing(User::getAge)) .map(User::getName) .collect(toList())
<a name="CH5NY"></a>
## lambda和方法引用
- lambda和方法引用都能配合Stream使用
- 但是方法引用有名字,更清晰,逻辑可以更复杂
<a name="8lOJ3"></a>
## Stream API:中间操作
仍然返回Stream的操作
- filter
- map
- sorted
- flatMap 每使用flatMap一次,降低一次维度
- ...
<a name="iw8T9"></a>
## Stream API: 终结操作
- 返回非stream的操作,包括void
- 一个流只能被消费一次
- forEach
- count/max/min
- findFirst/findAny
- anyMatch/noneMatch
- collect
- ...
<a name="9SwX8"></a>
## Optional的用法
- 是和函数式一起用的,而不是当做空指针用的
- Optional一般只是作为返回值,不推荐用于函数参数
```java
// 当做空指针的用法
Optional<User> user = users.stream().filter(User::isSurnameWang).findAny();
if (user.isPresent()) {
System.out.println(user.get().getName());
} else {
throw new IllegalStateException();
}
// 函数式用法(推荐)
Optional<User> optionalUser = users.stream().filter(User::isSurnameWang).findAny();
optionalUser.orElseThrow(IllegalStateException::new);
optionalUser.ifPresent(System.out::println);
// 进一步简化
Optional<User> optionalUser = users.stream().filter(User::isSurnameWang)
.findAny().orElseThrow(IllegalStateException::new);
optionalUser.ifPresent(System.out::println);
collector与Collectors
- collect操作是最强大的操作,把stream的元素收集起来
List<String> list = Arrays.asList("hello man", "it is about stream", "array list example");
list.stream()
.map(s -> s.split(""))
.flatMap(Stream::of)
.collect(Collectors.toList());
Collectors
- toSet()/toList()/toCollection()
- joining()
- toMap()
- groupingBy()/partitionBy(Predicate)
实现返回TreeSet:
.collect(Collectors.toCollection(TreeSet::new))
并发流
- parallelStream()
- 通过并发,可以提高互相独立的操作的性能
- 在使用正确的情况下,可以获得近似线性的性能提升
- 小心使用!性能要测试,使用时必须明确知道自己在做什么,明确没有线程不安全操作
- 如果不能明确自己在做什么,就不要用
// 统计[1, 1000_0000)之间的偶数数量
// 普通流
long startTime = System.currentTimeMillis();
IntStream.range(1, 1000_0000).filter(i -> i % 2 == 0).count();
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime); // 80
// 并发流
long startTime1 = System.currentTimeMillis();
IntStream.range(1, 1000_0000).parallel().filter(i -> i % 2 == 0).count();
long endTime1 = System.currentTimeMillis();
System.out.println(endTime1 - startTime1); // 33