Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a class like Optional but for non-optionals?

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);
like image 234
Lars Hartviksen Avatar asked Nov 15 '16 13:11

Lars Hartviksen


People also ask

Why is null better than optional?

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.

How do I make optional isPresent false?

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.

Should I use optionals Java?

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.

Should I use null or optional?

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.


3 Answers

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.

like image 165
Holger Avatar answered Oct 19 '22 17:10

Holger


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.

like image 35
Grzegorz Piwowarek Avatar answered Oct 19 '22 18:10

Grzegorz Piwowarek


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.

like image 4
Anton Balaniuc Avatar answered Oct 19 '22 18:10

Anton Balaniuc