1.Lambda表达式
Lambda为函数式编程,将一段代码当做参数传递。示例:
//Predicate接口是输入一个参数,返回布尔值。我们通过and方法组合两个Predicate条件,判断是否值大于0并且是偶数
Predicate positiveNumber = i -> i > 0;
Predicate evenNumber = i -> i % 2 == 0;
assertTrue(positiveNumber.and(evenNumber).test(2));
函数实现的是逻辑,不改变主体流程。示例的主体的判断数字是否大于0且是偶数。
2.stream
Lambda表达式可以用代码实现方法主体,利用这个特性,我们可以把集合的投影,转换,过滤等抽象成接口,然后通过Lambda表达式传入具体实现,这就是stream操作
List ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
double average = calc(ints);
double streamResult = ints.stream()
.map(i -> new Point2D.Double((double) i % 3, (double) i / 3))
.filter(point -> point.getY() > 1)
.mapToDouble(point -> point.distance(0, 0))
.average()
.orElse(0);
![](https://img.haomeiwen.com/i6504578/62b5d22d3b6f9367.png)
collect收集完成之后还可以进行一些动作
![](https://img.haomeiwen.com/i6504578/95de7d44527d2e79.png)
3.optional
optional规避代码判空逻辑
a.optionalDouble,optionalInt,OptionalDouble服务于基本类型的可空对象
b.optional也可用于引用类型,引用类型使用optional可以避免stream操作级联调用的空指针问题。
optional常用方法:
![](https://img.haomeiwen.com/i6504578/3b204ee5718b447c.png)
4.java8对函数式API增强
java8有一些类也实现了函数式功能,比如map做缓存的时候,不存在从数据库取进行缓存
private Product getProductAndCacheCool(Long id) {
return cache.computeIfAbsent(id, i -> //当Key不存在的时候提供一个Function来代表根据Key获取Value的过程
Product.getData().stream()
.filter(p -> p.getId().equals(i)) //过滤
.findFirst() //找第一个,得到Optional
.orElse(null)); //如果找不到Product,则使用null
5.forkJoin
ForkJoinPool和传统的ThreadPoolExecutor区别在于,前者对于n并行度有n个独立队列,后者是共享队列。如果有大量执行耗时比较短的任务,ThreadPoolExecutor的单队列就可能会成为瓶颈。这时,使用ForkJoinPool性能会更好。
因此,ForkJoinPool更适合大任务分割成许多小任务并行执行的场景,而ThreadPoolExecutor适合许多独立任务并发执行的场景
网友评论