Why not simply:
Copyreturn Optional.ofNullable(myMap.get(myKey));
JavaDocs
Answer from Eugene on Stack OverflowWhy not simply:
Copyreturn Optional.ofNullable(myMap.get(myKey));
JavaDocs
This
CopyOptional.of(myMap.getOrDefault(myKey, null));
or really
CopyOptional.of(null);
would've failed with a NullPointerException. As the javadoc states
Throws:
NullPointerException - ifvalueis null
Optional#ofNullable exists when you don't know if the value you're passing to it is null or not:
Parameters:
value- the possibly-null value to describe
And since Map#get(Object) already returns null when there is no entry for the given key
Returns:
the value to which the specified key is mapped, ornullif this map contains no mapping for the key
you don't need to use getOrDefault with a null value for the default. You can instead directly use
CopyOptional.ofNullable(myMap.get(myKey));
Viewing Optional as a Replacement for Checked Exceptions
java - How can I map Optional to another Optional if not present? - Stack Overflow
java - Using Optional to map and return data which is not used - Stack Overflow
Functional style of Java 8's Optional.ifPresent and if-not-Present? - Stack Overflow
I had this old post floating around that I never got to publishing. Maybe 8 years after Optional came out it's a bit late to try to clarify it, but my impression is that Optional has not been embraced the way it should be. The concept is clearly a central part of Kotlin, but I just don't see people writing methods that return Optional<T> as much as I would expect.
If you're interested, take a look and tell me how wrong I am:
https://www.pragmaticcoding.ca/java/optional
Since Java 9, there is Optional.or. It accepts a supplier for another Optional.
return cache.getUser(id).or(() -> repository.getUser(id));
You can create an optional based on a nullable value from other optionals:
public Optional<User> getUser(String id) {
return Optional.ofNullable(
cache.getUser(id).orElseGet(
() -> repository.getUser(id).orElse(null)
)
);
}
But your current solution is clearly more readable.
If you are using Java 9+, you can use ifPresentOrElse() method:
Copyopt.ifPresentOrElse(
value -> System.out.println("Found: " + value),
() -> System.out.println("Not found")
);
For me the answer of @Dane White is OK, first I did not like using Runnable but I could not find any alternatives.
Here another implementation I preferred more:
Copypublic class OptionalConsumer<T> {
private Optional<T> optional;
private OptionalConsumer(Optional<T> optional) {
this.optional = optional;
}
public static <T> OptionalConsumer<T> of(Optional<T> optional) {
return new OptionalConsumer<>(optional);
}
public OptionalConsumer<T> ifPresent(Consumer<T> c) {
optional.ifPresent(c);
return this;
}
public OptionalConsumer<T> ifNotPresent(Runnable r) {
if (!optional.isPresent()) {
r.run();
}
return this;
}
}
Then:
CopyOptional<Any> o = Optional.of(...);
OptionalConsumer.of(o).ifPresent(s -> System.out.println("isPresent " + s))
.ifNotPresent(() -> System.out.println("! isPresent"));
Update 1:
the above solution for the traditional way of development when you have the value and want to process it but what if I want to define the functionality and the execution will be then, check below enhancement;
Copypublic class OptionalConsumer<T> implements Consumer<Optional<T>> {
private final Consumer<T> c;
private final Runnable r;
public OptionalConsumer(Consumer<T> c, Runnable r) {
super();
this.c = c;
this.r = r;
}
public static <T> OptionalConsumer<T> of(Consumer<T> c, Runnable r) {
return new OptionalConsumer(c, r);
}
@Override
public void accept(Optional<T> t) {
if (t.isPresent()) {
c.accept(t.get());
}
else {
r.run();
}
}
Then could be used as:
CopyConsumer<Optional<Integer>> c = OptionalConsumer.of(
System.out::println,
() -> System.out.println("Not fit")
);
IntStream.range(0, 100)
.boxed()
.map(i -> Optional.of(i)
.filter(j -> j % 2 == 0))
.forEach(c);
In this new code you have 3 things:
- can define the functionality before the existing of an object easy.
- not creating object reference for each Optional, only one, you have so less memory than less GC.
- it is implementing consumer for better usage with other components.
By the way, now its name is more descriptive it is actually Consumer<Optional<?>>