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);
}
}
when I run the code the result is 57 (that is the correct result of 100, 20, 30, 80 average) but I create a Consumer that should increment the result by 3... but it seems to not work.
Can someone help me?
The ifPresent method of the Optional class is an instance method that performs an action if the class instance contains a value. This method takes in the Consumer interface's implementation whose accept method will be called with the value of the optional instance as the parameter to the accept method.
What is the ofNullable() method of the Optional class? The ofNullable() method is used to get an instance of the Optional class with a specified value. If the value is null , then an empty Optional object is returned.
Optional is a container object used to contain not-null objects. Optional object is used to represent null with absent value. This class has various utility methods to facilitate code to handle values as 'available' or 'not available' instead of checking null values.
The Consumer
action is actually being run but the body you provided modifies only a local instance which eventually gets lost. The ifPresent()
method should be used for performing side-effects(actions) only.
If you want to perform a calculation on a value held by an Optional
instance, use map()
instead.
ts1.opt1
.map(x -> x + 3).orElseThrow(...)
Remember to be careful when using get()
on an Optional
instance. Before you decide to use it, have a look at orElse
, orElseGet
, and orElseThrow
.
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
}
};
It is that case when turning a lambda into an anonymous class perfectly makes this all clear to understand.
The best possible way here is
ts1.opt1.map(x -> x + 3).ifPresent(System.out::println);
You could use an instance of a mutable class (e.g. the AtomicInteger
class):
Consumer<AtomicInteger> cns1 = x -> x.addAndGet(3);
which changes its state after accepting the Consumer<AtomicInteger>
(although it is not recommended, look at @pivovarit's answer).
Furthermore, the line
IntStream.of(100, 20, 30, 80).average().ifPresent(System.out::println);
might replace all your routine work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With