Java中关于Optional类的思考

181 阅读1分钟

众所周知,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));