众所周知,Optional是Java8里一个判断对象是否为空的类,它的作用是避免写一大堆ifelse的判断,我平时也很喜欢用它,但是最近却遇到了一点小问题,因此我研究了一下。
先来看下面这段代码,并猜测一下结果
Map<Integer, Integer> map = new HashMap<>();
Integer x = 1;
Optional.ofNullable(x)
.map(e -> map.put(1, 1))
.orElseGet(() -> map.put(2, 2));
我猜有的人会认为map的key就一个1吧,但是实际是1和2都有,我们知道orElse和orElseGet区别是,orElse不管对象是否为空都会执行,orElseGet只有对象为空的时候才会执行,那为什么看起来orElseGet也执行了两次呢。为了验证,我又贴了一段代码:
List<Integer> list=new ArrayList<>();
Integer x = 1;
Optional.ofNullable(x)
.map(e -> list.add(1))
.orElseGet(() -> list.add(2));
结果是list长度为1,并且里面的元素为1。
这引发了我的思考,后来我发现add方法返回的是添加的值,put方法返回的是覆盖前的value值,因为是第一次添加,所以返回的是null。最终我在源代码找到了答案:
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
结论:原来Optional的map方法返回参数方法返回值,当ofNullable对象为空或者map返回值为空,执行orElseGet方法
解决方法:
Integer x = 1;
Optional.ofNullable(x)
.map(e -> map.compute(1, (k, v) -> 1))
.orElseGet(() -> map.put(2, 2));