Java Optional / Stream 使用总结
Optional
1. map() 映射
map(i -> query(i)) //lambda形式获取对象
map(Student::getName)//获取student对象的name属性
2. filter() 过滤
filter(stu -> stu.getName().equals("xxx"))
3. orElse() 消费Optional
String stuName = Optional.ofNullable(student)
.map(Student::getName) // 获取student对象的name属性
.filter(stu -> stu.getName().equals("xxx"))// 过滤name为 xxx
.orElse("Qa");// 如果不存在xxx,即返回Qa
4. orElseThrow() 如果不存在则返回异常
orElseThrow( () -> new Exception())
5. ifPresent()
6. isPresent() --boolean
Java8 Optional类仅支持到 if 判空 ,尚未同时支持 else 执行业务逻辑
-- e.g.
Optional.ofNullable(student).ifPresent(stu ->{
```
});
例子中可以看到仅支持判断对象student不为null时去执行代码逻辑
Java9+ Optional类做到支持else执行逻辑
-- e.g.
Optional.ofNullable(student).ifPresentOrElse(stu ->{
```
} , () ->{
```
});
Stream
1. map()
2. filter()
3. forEach()
forEach(stu ->{
```
});
4. forEachOrdered()
5. collect()
collect(Collectors.toList()) 转为list集合
6. sorted() 排序
//默认升序
sorted(Comparator.comparing(Student::getId)
.thenComparing(i ->i.getNo()))
sorted(Comparator.comparing(Student::getId).reversed())//降序
7. reduce() 计算
list.stram()
.map(BigDecimal::new)
.reduce(BigDecimal.ZERO, BigDecimal::add)
[ZERO-->ONE]
[add -->subtract, multiply,divide ]
8. distinct () 去重
set集合
9. .skip(起始索引).limit(终止索引)
等等
parallelStream 并行流
Stream具有平行处理能力,处理的过程会分而治之,也就是将一个大任务切分成多个小任务,这表示每个任务都是一个操作,因此像以下的程式片段:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
numbers.parallelStream()
.forEach(out::println);
你得到的展示顺序不一定会是1、2、3、4、5、6、7、8、9,而可能是任意的顺序,就forEach()这个操作來讲,如果平行处理时,希望最后顺序是按照原来Stream的数据顺序,那可以调用forEachOrdered()。例如:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
numbers.parallelStream()
.forEachOrdered(out::println);
stream or parallelStream?
上面我们也看到了parallelStream所带来的隐患和好处,那么,在从stream和parallelStream方法中进行选择时,我们可以考虑以下几个问题:
- 是否需要并行?
- 任务之间是否是独立的?是否会引起任何竞态条件?
- 结果是否取决于任务的调用顺序?
对于问题1,在回答这个问题之前,你需要弄清楚你要解决的问题是什么,数据量有多大,计算的特点是什么?并不是所有的问题都适合使用并发程序来求解,比如当数据量不大时,顺序执行往往比并行执行更快。毕竟,准备线程池和其它相关资源也是需要时间的。但是,当任务涉及到I/O操作并且任务之间不互相依赖时,那么并行化就是一个不错的选择。通常而言,将这类程序并行化之后,执行速度会提升好几个等级。
对于问题2,如果任务之间是独立的,并且代码中不涉及到对同一个对象的某个状态或者某个变量的更新操作,那么就表明代码是可以被并行化的。
对于问题3,由于在并行环境中任务的执行顺序是不确定的,因此对于依赖于顺序的任务而言,并行化也许不能给出正确的结果。