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
