It is handy to declare Functions to map values and consume them if they are present.
In the situation that you have several mandatory objects, and several Optionals, I find myself wrapping the others in Optional.of(mandatoryObject) as well so I can use the same expressions on them without writing it all backwards.
Food vegetables = Food.someVegetables();
Optional<Food> condiment = Food.someCondiment();
Optional<Food> spices = Food.someSpices();
condiment.map(prepare).ifPresent(putOnPlate);
spices.map(prepare).ifPresent(putOnPlate);
But then I don't like this code:
putOnPlate.accept(prepare.apply(vegetables));
so I wrap it:
Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);
But that is just wrong, because the vegetables (in this example) are not in fact optional. They are very important and I just gave everyone the impression that they are optional.
So my question is : Is there some class in java like java.util.Mandatory so I can write:
Mandatory.of(vegetables).map(prepare).definitelyPresentSo(putOnPlate);
In a nutshell, the Optional class includes methods to explicitly deal with the cases where a value is present or absent. However, the advantage compared to null references is that the Optional class forces you to think about the case when the value is not present.
If you just want an Optional returning false for isPresent() , you don't need to mock the Optional at all but just create an empty one. Of course this test only tests that the mock object actually returns the stubbed return value, but you get the idea.
Optional is primarily intended for use as a method return type where there is a clear need to represent "no result," and where using null is likely to cause errors. A variable whose type is Optional should never itself be null ; it should always point to an Optional instance.
The reason why Optionals are so useful is because with Optionals it forces you to represent your data in such a way that you can't invoke a method from null . Without Optionals it's not only possible, it's extremely easy to. In other words, you avoid sloppy logic and stupid errors.
Yes, there is such an API. You may replace
Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);
with
Stream.of(vegetables).map(prepare).forEach(putOnPlate);
now having to live with the fact that the single-element Stream
is a special case of the stream of arbitrary elements (including the possible empty stream).
But you can handle all mandatory elements at once
Stream.of(mandatory1, mandatory2, mandatory3 /* etc */).map(prepare).forEach(putOnPlate);
It would be even possible to incorporate the optional elements, but it will not be as convenient as it should be, as Optional.stream()
will be introduced not until Java 9.
The main idea behind Optional
is abstracting nullability(getting rid of null checks) and providing a fluent API for working with optional values.
In the case of a value that is always present, there is nothing to abstract(at least nothing with a practical value) so no such tools exist in the pure Java.
In other functional languages, you have multiple 'monadic' tools like Optional
available for different use-cases. If you want to bring them to Java, Javaslang is probably the best place to look at. You can find there tools like Option
, Try
, Lazy
, Validation
, Either
, Future
, Tuple
and the whole Collections API
that allows coding in a similar fashion you described.
I might be wrong, but if you don't like to use Optional
you can just use a Stream
of just one object. So instead of
Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);
you can just use:
Stream.of(vegetables).map(prepare).forEach(putOnPlate);
The result is going to be identical. Both methods will throw NPE
if vegetables are null.
Arrays.asList(10, null).forEach(value -> {
Optional.of(value).map(x -> x.toString()).ifPresent(System.out::println);
Stream.of(value).map(x -> x.toString()).forEach(System.out::println);
});
NPE safe version is going to be
Optional.ofNullable(value).map(x -> x.toString()).ifPresent(System.out::println);
Stream.of(value).filter(Objects::nonNull).map(x -> x.toString()).forEach(System.out::println);
Optional
is just a container for an object which may or may not contain a non-null value.
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