I have to write a Predicate in Java where I can query the input to predicate to get two Optional<Integer>
objects. I have to return true or false based on the combined value of the two Optionals. Is there some better way to do it other than checking the isPresent()
and then get()
those values and add.
// Here assuming the comparingValue and integer1 and integer2 are all initialised with values.
// The isGreaterOrEqual function has an implementation.
int comparingValue;
Optional<Integer> integer1;
Optional<Integer> integer2;
if (integer1.isPresent() && integer2.isPresent())
return isGreaterOrEqual(comparingValue, integer1.get() + integer2.get());
if (integer1.isPresent())
return isGreaterOrEqual(comparingValue, integer1.get());
else if (integer2.isPresent())
return isGreaterOrEqual(comparingValue, integer2.get());
else
return false;
Here is another approach:
return Stream.of(integer1, integer2)
.flatMap(Optional::stream)
.reduce((a, b) -> a + b)
.map(t -> isGreaterOrEqual(comparingValue, t))
.orElse(false);
It is not without using → Thanks to Hulk's comment, it actually is without isPresent
and get
, but it is fluent-style.isPresent
and get
.
What happens here in the abovementioned code, is we build a stream of the two Optional<Integer>
s, and then:
comparingValue
comparingValue
false
.The advantage of this approach is that it allows to add more optionals if desired:
public boolean test(int comparingValue, Optional<Integer> optionalIntegers...) {
Stream.of(optionalIntegers)
Regarding your comments about 'generalization' — of course, you cannot use the +
operator with objects other than String
and the wrapper classes of numeric types. If we assume your class has a merge
method with the following signature:
Money add(Money m1)
then you only need to replace the line with reduce
to the following:
.reduce((a, b) -> a.add(b))
or just
.reduce(Money::add)
For Java 8, you could replace .flatMap(Optional::stream)
by
.filter(Optional::isPresent)
.map(Optional::get)
and you're good to go.