为什么Java的Optional在ifPresent()中不调用Consumer?

Why Java's Optional doesn't call Consumer in ifPresent()?

public class TestSupplier {

Optional<Integer> opt1;

public static void main(String[] args) {
    // TODO Auto-generated method stub

    TestSupplier ts1 = new TestSupplier();

    ts1.opt1 = ts1.average(100,20,30,80);
    Consumer<Integer> cns1 = (x) -> x += 3;
    ts1.opt1.ifPresent(cns1);
    System.out.println(ts1.opt1.get());

}


private Optional<Integer> average(int... n1) {
    if (n1.length == 0) return Optional.empty();
    int sum = 0;
    for(int score: n1) sum += score; 
    return Optional.of(sum/n1.length);

}

}

当我 运行 代码时,结果是 57(这是 100、20、30、80 平均值的正确结果),但我创建了一个应该将结果递增 3 的消费者...但是好像不行。

有人可以帮助我吗?

Consumer<Integer> cns1 = new Consumer<Integer>() {
    public @Override void accept(Integer x) {
        // x is a local variable
        x += 3; // unboxing, adding, boxing 
        // the local variable has been changed
    }
};

正是这种情况,将 lambda 转换为匿名 class 完美地使这一切变得清晰易懂。

这里最好的方法是

ts1.opt1.map(x -> x + 3).ifPresent(System.out::println);

您可以使用可变 class 的实例(例如 AtomicInteger class):

Consumer<AtomicInteger> cns1 = x -> x.addAndGet(3);

它在接受 Consumer<AtomicInteger> 后改变了它的状态(虽然不推荐,看看 @pivovarit 的回答)。

此外,行

IntStream.of(100, 20, 30, 80).average().ifPresent(System.out::println);

可能会取代您所有的日常工作。

Consumer 操作实际上是 运行 但您提供的正文仅修改了最终丢失的本地实例。 ifPresent() 方法应该只用于执行副作用(动作)。

如果要对 Optional 实例持有的值执行计算,请改用 map()

ts1.opt1
  .map(x -> x + 3).orElseThrow(...)

请记住在 Optional 实例上使用 get() 时要小心。在决定使用它之前,请先查看 orElseorElseGetorElseThrow.