I have the following problem. Let's say you have 2 Optional
variables
Optional<Contact> c1 = ...
Optional<Contact> c2 = ...
and a method which needs 2 variables of type Contact
void match(Contact c1, Contact c2) {...}
and you need to unwrap both c1 and c2 Optional
vars and pass them into the match()
method.
My question is "Which is the most elegant way to do that in Java 8?"
So far I've found 2 ways:
by using isPresent
if (c1.isPresent() && c2.isPresent()) {
match(c1.get(), c2.get());
}
by using nested ifPresent
c1.ifPresent((Contact _c1) -> {
c2.ifPresent((Contact _c2) -> {
match(_c1, _c2);
});
});
Both ways are terrible in my opinion. In Scala I can do this:
for {
contact1 <- c1
contact2 <- c2
} yield {
match(contact1, contact2);
}
is there a way in Java 8 to do it neater than I outlined above?
Use the Optional Container Object to Have Optional Parameters in Java. In Java, Optional is a container object that may or may not contain a non-null value. If a value is present, then the isPresent() method will return true, and the get() method will return the value.
So, to overcome this, Java 8 has introduced a new class Optional in java. util package. It can help in writing a neat code without using too many null checks. By using Optional, we can specify alternate values to return or alternate code to run.
There are no optional parameters in Java. What you can do is overloading the functions and then passing default values.
Solution you provided in scala is just syntax sugar for using flatMaps internally. You can use flatmaps in Java 8 too (but there are no syntax sugar for it).
c1.flatMap(contact1 -> c2.flatMap(contact2 -> match(contact1, contact2)));
it is almost the same thing as solution 2 you provided. You also can use applicative functor from https://github.com/aol/cyclops-react (I'm one of contributors) or any other functional java 8 library.
Applicative functor
Optional<String> o3 = Maybe.fromOptional(o1).ap2(String::concat).ap(o2).toOptional();
For-comprehension
Do.add(o1)
.add(o2)
.yield(a->b->a.concat(b));
You could desugar the Scala for-comprehension to map/flatMap in Java 8 with a function like:
public static <T,K,V> Optional<V> map2(Optional<T> opt1, Optional<K> opt2, BiFunction<T, K, V> f) {
Optional<V> result = opt1.flatMap(t1 -> opt2.map(t2 -> f.apply(t1, t2)));
return result;
}
And then pass your function match
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