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 ...但它似乎不起作用。
有人可以帮助我吗?
答案 0 :(得分:5)
Consumer
动作实际上正在运行,但您提供的主体仅修改最终会丢失的本地实例。 ifPresent()
方法仅用于执行副作用(动作)。
如果您要对Optional
个实例所持有的值执行计算,请改用map()
。
ts1.opt1
.map(x -> x + 3).orElseThrow(...)
在get()
实例上使用Optional
时请务必小心。在您决定使用它之前,请查看orElse
,orElseGet
和orElseThrow
。
答案 1 :(得分:1)
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变成一个匿名类完全可以理解这一点。
这里最好的方法是
ts1.opt1.map(x -> x + 3).ifPresent(System.out::println);
您可以使用可变类的实例(例如AtomicInteger
类):
Consumer<AtomicInteger> cns1 = x -> x.addAndGet(3);
在接受Consumer<AtomicInteger>
后更改其状态(虽然不推荐,但请查看@pivovarit的答案)。
此外,该行
IntStream.of(100, 20, 30, 80).average().ifPresent(System.out::println);
可能会取代你所有的日常工作。