Use Optional instead of null check - java

I have to check if an attribute of an object is null or not. Depending on the above check I have to update another attribute in the same object. Is it possible to use Optional class and its methods to replace null checks?
if(userData.getSubscription()==null){
userData.setFees(Enum.ZERO);
} else {
userData.setFees(Enum.HUNDRED);
}
Let me know if this can be replaced with a single line using Java 8 Optional class or other features.

Maybe you want:
userData.setFees(Objects.isNull(userData.getSubscription()) ? Enum.ZERO : Enum.HUNDRED)

You could do something like
Optional::ofNullable(userData.getSubscription()).map(any -> Enum.HUNDRED).orElse(Enum.ZERO);
However I don't see much benefit to that over #T.J. Crowder's suggestion from the comments
userData.getSubscription() == null ? Enum.ZERO : Enum.HUNDRED

The main use of Optional is to prevent you from forgetting to check for null. Thus, it would only be useful if the Optional type was returned from getSubscription(). Then you could do:
userData.setFees(userData.getSubscription().map(x -> Enum.HUNDRED).orElse(Enum.ZERO));
But if you can't or don't want to change getSubscription() to return Optional, then there is no point in using Optional here. Just do this:
userData.setFees(userData.getSubscription() == NULL ? Enum.ZERO : Enum.HUNDRED);
By the way, if Enum.ZERO and Enum.HUNDRED are just names representing 0 and 100, then that's not a good idea. The words "ZERO" and "HUNDRED" are just as much a "magic number" as the numbers 0 and 100 themselves. You should name your enums something descriptive like "FREE_OF_CHARGE" and "FULL_PRICE".

Related

Is using Optional.ofNullable as a replacement for the ternary operator a good practice?

Consider the usage of this expression:
String hi = Optional.ofNullable(sayHi()).orElse("-");
which effectively corresponds to this ternary expression:
String hi = sayHi() != null ? sayHi() : "-";
Is this usage of Optional.ofNullable with a method call a good practice? Or just extra verbose coding?
I recognise that Optional.ofNullable actually creates a variable and avoids calling the sayHi() method twice. To avoid this problem you actually could create an extra variable but this adds to the verbosity of the ternary option:
String hi = sayHi();
hi = hi != null ? hi : "-";
On the other hand Optional.ofNullable creates in case of hi not being null an extra Optional object. So there is for sure more overhead to it.
So there seem to be some pros and cons to using this type of construct to replace the ternary constructor.
By the way: this is the Java 8 implementation of Optional.ofNullable:
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
In JDK 9 or later, use this:
String hi = Objects.requireNonNullElse(sayHi(), "-");
This avoids having to repeat sayHi() if a ternary operator is used, or to assign its value to a local variable that is reused within the ternary. It might be a small improvement. It also sidesteps the question of whether to use Optional. :-)
Whenever I come to think of using the Optional API for a specific purpose I always remind my self of what it was intended to do and why it was brought into the JDK and i.e.
Optional in intended to provide a limited mechanism for library method
return types where there is a clear need to represent “no result” and
where using null for this is overwhelmingly likely to cause errors - Stuart Marks
Optional is primarily focused on a return type that might or might not have a return value.
Over using this construct like in this specific example of yours just causes extra memory allocation and GC overhead.
I’d keep things simple and instead do:
String hi = sayHi();
if(hi == null) hi = “-“;
...
Is this usage of Optional.ofNullable with a method call a good practice?
Conceptually, it's a bad practice. The basic idea is to represent the absence of a return value, not to wrap everything that might be null. I am strongly against this usage.
Or just extra verbose coding?
It looks to me like a failed attempt to make your code more fashionable. ("Look, we are using brand-new Optional from Java 8!")
I prefer readability and clarity over conciseness.
This Optinal usage doesn't provide clarity but raises questions:
Why do you wrap the variable?
What are you going to do with this Optional?
Will it be used/returned below?
It doesn't give brevity either: your second line is even shorter.
To avoid this problem you actually could create an extra variable but this adds to the verbosity of the ternary option.
You aren't creating an extra variable. The one-line version could be:
String hi = (hi = sayHi()) != null ? hi : "-";
Though, your two-line suggestion is absolutely fine:
String messageContent = sayHi();
String hi = messageContent != null ? messageContent : "-";
If you're going to allow Optional into your workflow then you should consider modifying the sayHi() method so that it returns Optional<String> which will make the result more elegant:
hi = sayHi().orElse("-");
If you don't want to introduce Optional into your workflow (because it does create an additional object to contain the optional value) then you're better off sticking with simple null checks and the ternary operator.
With regard to the performance costs of Optional (such as increased garbage collection), you'd need to profile your application and decide whether or not this was a real concern.
Additionally, if you're mostly interested in String then be aware of the Objects.toString(Object, String) method which return a default value if the object is null:
hi = Objects.toString(hi, "-");
This is tidier and more elegant than writing out the code manually.
In brief: avoid the Optional type.
The main argument for Optional on return types is, "It's too easy for clients to forget to handle the possibility of a null return value. Optional is ugly and in your face, so a client is less likely to forget to handle the possibility of an empty return value. Everywhere else, programmers should continue to use normal references, which might be null."
I wrote a discussion of the pros and cons of using Java's Optional type: Nothing is better than the Optional type.
I think it's mostly a matter of personal taste.
From my point of view it would be more meaningful to just return an Optional<String> and let the caller deal with a missing value.
Optional, being a monadic type, can be leveraged for more then just getting an alt-value.
On the other end your operator seems terse enough, if used consistently it could be practical.
I don't think performance is a big issue here.

How to performe a null-check for an empty Optional

I'm currently working with some repository functions, like .findById(). Now I want to check, if there was an entry returned for the requested id. I'm currently doing this by performing a null-check.
Optional<Entry> entryOptional = entryRepository.findById(id);
if (entryOptional != null) {
// do sth. ...
}
The .findById() documentation says, that the function will...
return the entity with the given id or Optional#empty() if
none found
So is my current implementation with the null-check working as expected? Or do I have to check something like:
if (!entryOptional.isEmpty()) {
// do sth. ...
}
Checking whether an optional is null or not is intrinsically wrong.
Optionals where created in order to negate the need for null checks, by introducing the notion of emptiness.
Essentially an optional is a wrapper for a value, for which it can have two states. Either having a value or being empty. This is done via using Optional#isPresent. You can check more on this on the related documentation here.
What this does essentially is the following:
public boolean isPresent() {
return value != null;
}
A nicely implemented method (as the one you mention above) will either return an optional with a value or an empty Optional (as it is mentioned in the documentation).
Optionals offer a good amount of methods that you can operate of them without the need for emptiness checks.
For example, in your code you could:
entryRepository.findById(id).ifPresent(() -> {
//some operation
});
Which basically accepts an consumer and executes it in case the value of the optional is not null.
Alternative you could use mapping functions etc etc.
I suggest you have a good look at the documentation for more.
So is my current implementation with the null-check working as expected?
No. Like the method says, it returns the entity, or Optional.empty; it does not return null.
Your second version is correct.
Optionals are created to remove null checks on that field and to do operations on that field without the care of it being null.
You can check with Optional.isPresent() at the end if it contains any value or not.
So yes, your second approach is correct.

Convenient way of checking equality for Optionals

I'm looking for a more convenient way of proofing equality for an Optional value.
This is what an Oracle Blog post suggests:
Optional<USB> maybeUSB = ...;
maybeUSB.filter(usb -> "3.0".equals(usb.getVersion())
.ifPresent(() -> System.out.println("ok"));
IMHO results in something like
if (maybeUSB.filter(c -> "3.0".equals(c.getVersion())).isPresent()) {
...
}
Of course that's kind of a poor example because it compares the Version and not the instance of USB itself but I think it should still proof my point.
Is this really as good as it gets?
No
boolean presentAndEquals(Object)
or
boolean deepEquals(Object)
Am I missing something here?
EDIT:
I'm not that happy with Optionals.equals either.
Do I really have to box an Object first to instantly unbox and check for equality ?
EDIT II:
Pretty damn happy with:
optional
.filter(nonOptional::equals)
.isPresent()
nowadays.
After some years of functional programming, if looses a lot of relevance.
You have many options.
Already noted:
boolean isEqual = maybeFoo.equals(Optional.of(testFoo));
Alternatively:
boolean isEqual = maybeFoo.isPresent() && maybeFoo.get().equals(testFoo);
Or:
boolean isEqual = testFoo.equals(maybeFoo.orElse(null));
These last two do have slightly different semantics: each returns a different value when maybeFoo is empty and testFoo is null. It's not clear which is the correct response (which I guess is one reason there's not a standard API method that does this).
You can probably come up with others if you read the Optional API doc and apply some thought. There's nothing magic that's absent from the docs.
More generally, if you're knocking against this often enough for it to bother you, you might be approaching Optional with the wrong philosophy.
As I see it, Optional is about acknowledging that something won't always be present, and that you need (sometimes verbose) code to handle that.
This should be the exception. Wherever possible, try and create variables that can't be null or Optional.empty().
In situations where this is unavoidable, embrace the fact that you need extra code.
Optional implements the equals method directly:
if (maybeUSB.equals(Optional.ofNullable(testUSB))) {
...
}
(you can also use Objects.equals rather than calling equals directly)
EDIT:
If you want both not present to be false, you can do this:
if (maybeUSB.equals(Optional.ofNullable(testUSB)) && maybeUSB.isPresent()) {
...
}
Would this work?
if (maybeUSB.map(c -> c.getVersion().equals("3.0")).orElse(false))

Java NullPointerException check on chained methods

I want to check for a null pointer when accessing a field several classes deep (in a chain of get methods). However, if one of the earlier methods is null I get a NullPointerException anyways.
This is what I want to check, though it can still get a NullPointerException:
if(x.getLocation().getBuilding().getSolidFuelInd() != null)
pol.setWood_heat_ind(x.getLocation().getBuilding().getSolidFuelInd() ? "Y" : "N");
This the behavior I want the above code to exhibit:
if(x.getLocation() != null)
if(x.getLocation().getBuilding() != null)
if(x.getLocation().getBuilding().getSolidFuelInd() != null)
pol.setWood_heat_ind(x.getLocation().getBuilding().getSolidFuelInd() ? "Y" : "N");
The field on the pol is optional and should only be set if the above getter is not null. However the building and location objects could also be null, so now I must check to that they're valid.
Is there any sort of shorter way to check all the above like I want?
With Java 8's Optional<> class, you can map a value as so:
Optional.of(x)
.map(ClassOfX::getLocation)
.map(Location::getBuilding)
.map(Building::getSolidFuelInd)
.map(solidFuelInd -> solidFuelInd ? "Y" : "N")
.ifPresent(pol::setWood_heat_ind);
map calls will only be executed if the value of the optional isn't null thus avoiding the NullPointerException.
ifPresent's purpose is to call your setWood_heat_ind only if a value if available.
A nice single-call equivalent to null checks.
If its code reduction you want then you can save each call in a variable.
// note: Replace type with the correct type
type location = x.getLocation();
type building = location == null ? null : location.getBuilding();
// note: you don't have to check for null on primitive types
pol.setWood_heat_ind(building != null && building.getSolidFuelInd() ? "Y" : "N");
This is much cleaner and easier to follow.
Food for thought, you don't check for null on primitive types boolean, int, byte etc. so the last null check on building.getSolidFuelInd() is not needed
Java 8 has Optional<T> which would make for one chained expression, though verbose.
However Java 8 also has Stream<T> and you could have a
"stream" of 0 or 1 item, and then query with lambdas.
x.getLocation()
.map((loc) -> loc.getBuilding())
.map((building) -> building.getSolidFuelInd() != null)
.findFirst()
.ifPresent ...
Or
x.getLocation()
.map(Location::getBuilding)
.map(Building::getSolidFuelInd())
.filter(fuelInd -> fuelId != null)
.findFirst()
.ifPresent ...
It probably will be a matter of slow coming to terms with an application of those new terms.
You could just catch the exception
try{
pol.setWood_heat_ind(x.getLocation().getBuilding().getSolidFuelInd() ? "Y" : "N");
}catch(NullPointerException e){
//e.printStackTrace(); or whatever you want
}
(Referring to your possible solution) checking for the returned values implies invoking the same methods more the once, that's why I would use this solution.
As Jay Harris pointed out, you can obviously check the values and save the return parameter, without having to invoke the same method again. You can do it in many different ways, here one
Object loc=null,build=null;
Boolean SFI = ((loc=x.getLocation())==null?null:
((build=loc.getBuilding())==null?null:
(build.getSolidFuelInd())));
if(SFI!=null)pol.setWood_heat_ind(SFI?"Y":"N");
But is it worth it? I made this more complicated than it could on purpose, but anyway, why doing that if you can try...catch in two simple lines?

How to use Guava Optional in this scenario

I have a scenario which I want to use Guava Optional, but there is problem:
The method is like this:
private static void method(Optional<Object> myOptional) {
if(myOptional.isPresent()) {
....
}
}
The myOptional can contain non-null value, null value, or absent(). A null is a valid input in this scenario.
In the method, I want to process non-null value and null value using differnt ways, but ignore absent value.
However, if I use isPresent here, the null value will be ignored as well. But if I use "get" method, the absent value will throw exception. If I use orNull, the absent value also returns as null.
I am not sure what I shall do here. But I think the reason to create Optional is to differentiate null and absent so that null becomes a valid meaningful value. But it looks like there is no method in Optional that allows me to achieve my usecase.
Can anyone help? Thanks.
You can't do that.
The javadoc says it explicitly: an Optional may contain a non null reference. Never a null one.
What you can do is create an Optional.fromNullable(whatever).orNull(). But an Optional will never differentiate a null value from absent, since it is not what it is meant to do!

Categories

Resources