We have all seen that kind of code
if (myObject!= null
&& myObject.mySubObject() != null
&& myObject.mySubObject().getSpecificValue() != null
&& !myObject.mySubObject().getSpecificValue().isEmpty()
) {
......
}
How could I write this the clean way ?
You can do chaining with Optional:
Optional.ofNullable(myObject)
.map(o -> o.mySubObject())
.map(so -> so.getSpecificValue())
.map(sv -> sv.isEmpty())
.orElse(false)
Or with method references even shorter (does the same):
Optional.ofNullable(myObject)
.map(Foo::mySubObject)
.map(Bar::getSpecificValue)
.map(Baz::isEmpty)
.orElse(false)
where Foo, Bar and Baz are the names of the respective classes.
If you are using someone else's code then you're really stuck handling for a possible null. On the other hand, if you have control over the code base then never return a null object, and make that a rule across your entire application.
This may sound bad at first but I have developed several enterprise-level applications and this is a very effective way to make the code consistent and much more readable.
So, now, this
if (myString != null && !myString.isEmpty()) {
becomes simply
if (!myString.isEmpty()) {
In lue of that option use the new Optional feature in J8 as it is intended for that purpose.
Related
If I try to do a .equals() on a null string in java, a null pointer exception will be thrown. I am wondering, if I am trying to compare if a string is equal to some constant string, can I do the following:
MY_CONSTANT_STRING.equals(aStringVariable)
I know it will work, but is this just really poor code?
This is a standard Java idiom jokingly called a Yoda condition.
Personally I prefer to handle the null case explicitly, but the Yoda way is used a lot and any experienced Java programmer should be able to understand what is going on immediately. It's fine to use.
is this just really poor code?
No, this is the way many people would code the statement to avoid NPE.
What you've got is fine. It's even possible to use a String literal.
if( "value".equals(variable) ) {
...
If you don't like that, you can always explicitly check for null and equality, and combine the two checks with &&. The short circuiting of the operator will make sure you never get a NPE.
if( (variable != null) && variable.equals("value") ) {
...
I would keep the "CONSTANT.equals(possibleNull)" code without the null test only if it is a normal condition that the variable could be null - for instance because it just came out of a property map.
Similarly you can get away with not checking for null in instanceof-checks - like:
Food dinner = map.get("dinner");
if (dinner instanceof Soup) {
((Soup)blah).eat();
} // We don't care if it is a Fish or null
But if you really did not expect null, you should explicitly check for that in a separate if-test, and handle it appropriately. It's generally better to catch such data errors early rather than later.
Nope, it's usually done to avoid NPE. However, I usually prefer to do explicit check for null.
If you are concerned about the quality of your code, write a helper class that takes care of equality test:
public class ObjectHelper {
public static boolean testEquality(Object o1, Object o2) {
if (o1 == null && o2 == null) return true;
if (o1 == null) return false;
return o1.equals(o2);
}
}
Then use it like this:
if (ObjectHelper.testEquality(aStringVariable, My_CONSTANT_STRING))
Your so-called constant MIGHT stop being constant. It might be read from a configuration file some time in the future.
This question already has answers here:
Chaining Optionals in Java 8
(10 answers)
Closed 1 year ago.
I am trying to get value from multiple Optional based on priority and condition
Lets say in following two set of optional the activitys that can be return are Walking and Swimming. If there is any activity in either of the optional and if swimming is there, then swimming should get preference else walking. If there are no activities then this will return empty. I managed to write it but there are too many conditions and wanted to see if there is a smart way of avoiding so many conditions
public Optional<Activity> getActivity(){
Optional<Activity> activityWhenSunShines= getActivityWhenSunShiningForUser(u);
Optional<Activity> activityWhenDayIsGood= getActivityWhenDayIsGoodForUser(u);
if(activityWhenSunShines.isPresent() && Activity.SWIMMING == activityWhenSunShines.get()){
return activityWhenSunShines;
}else if(activityWhenDayIsGood.isPresent() && Activity.SWIMMING == activityWhenDayIsGood.get()){
return activityWhenDayIsGood;
}else if(activityWhenSunShines.isPresent()){
return activityWhenSunShines;
}else if(activityWhenDayIsGood.isPresent()){
return activityWhenSunShines;
}else{
return Optional.empty();
}
}
This code
activityWhenSunShines.isPresent() && Activity.SWIMMING == activityWhenSunShines.get()
can be converted to a more functional style, without isPresent followed by get
activityWhenSunShines.map(a -> a == Activity.SWIMMING).orElse(false)
The last 3 cases can be replaced with Optional.or (added in Java 9).
That gives you:
Optional<Activity> activityWhenSunShines = getActivityWhenSunShiningForUser(u);
Optional<Activity> activityWhenDayIsGood = getActivityWhenDayIsGoodForUser(u);
if(activityWhenSunShines.map(a -> a == Activity.SWIMMING).orElse(false)){
return activityWhenSunShines;
} else if(activityWhenDayIsGood.map(a -> a == Activity.SWIMMING).orElse(false)){
return activityWhenDayIsGood;
}
return activityWhenSunShines.or(() -> activityWhenDayIsGood);
Patient: Doctor, doctor! It hurts when I smash this hammer against my face!
Doctor: Okay. Stop doing that then.
Optional (in the java ecosystem, at least) is mostly bad. It's fine for stream terminal return values and not much else.
The much better alternative is to just have a data structural setup where neither null nor Optional are relevant. The next-best alternative is to use null (and add some nullity annotations if you prefer compile-time checks). A very distant crappy third solution is the dreaded Optional.
For example, here, why not have an Activity.NOTHING, and spec gAWSSFU to never return null?
Here's what your code would look like if you did that:
Activity activityWhenSunShines = getActivityWhenSunShiningForUser(u);
Activity activityWhenDayIsGood = getActivityWhenDayIsGoodForUser(u);
return
(activityWhenSunShines == Activity.SWIMMING || activityWhenDayIsGood) ? Activity.SWIMMING :
activityWhenSunShines != Activity.NOTHING ? activityWhenSunShines :
activityWhenDayIsGood;
If instead of nothing you prefer null here, it's the exact same code, just replace Activity.NOTHING with null and you're good to go.
Optional doesn't compose (generics has co/contra/in/legacy-variance, in order to be composable. The nullity dimension introduced by Optional doesn't play that game; you e.g. can write a method that takes in a list of Number or some subclass thereof. You can't write a (type-safe) method that takes a list of either String or Optional<String>. Optional is also entirely backwards incompatible (e.g. map.get(x) does not return Optional<V> and never will, given that java doesn't break backwards compatibility, especially not of such an oft-used method). If you want compile-time-checked null safety, have a look at null annotation frameworks, such as the one baked into your IDE (both Eclipse and IntelliJ have their own system, fully supported with compile time checks), or use e.g. checker framework's, which is more flexible than what eclipse and intellij offer.
I have gone through several null check related questions in Java and the best practices around it.
After long search , I can see Objects.nonNull () serves the purpose though it looks Orange instead of Apple.
Now i have a following check using Objects.nonNull() and short-circuiting logical AND.
if (Objects.nonNull (obj1) &&
Objects.nonNull (obj1.getObj2()) &&
Objects.nonNull (obj1.getObj2().getObj3 ())
{
obj1.getObj2().getObj3().doSomething();
}
I find it is more redundant and less readable when i clearly know my intention.
Is there any other approach to handle it in functional way to assert the non null state of the deeper object without facing Null pointer exception.
Using !=null is the normal way to do null-checks, but here's an alternative way that allows you to chain them using Optional.
Optional.ofNullable(obj1).map(class1::getObj2)
.map(class2::getObj3)
.ifPresent(class3::doSomething);
and you can use a lambda expression in place of any of the method references if the code you want to execute is not a simple function call.
Optional.ofNullable(obj1).map(x -> x.getObj2())
.map(x -> x.getObj3())
.ifPresent(x -> {
System.out.println("Now I can use my obj3 "+x);
});
I'm trying to know whether we can write null check pointer in the same statement in Java, as we do in groovy? I've four places to check null. Can this be more simplified?
if(doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM") != null) {
if(doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0) != null) {
Node searchResultNode = doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0);
if(searchResultNode != null) {
}
}
}
as
doc.getDocumentElement()?.getElementsByTagName("SEARCH-RESULT-ITEM")?.item(0)
Is it possible
You asked if it is possible to write Groovy-like code in a regular Java project. The simple answer is no.
However, the statement can be simplified by combining the null checks into one condition. In addition, if doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0) is not null we don't need to check the local variable.
So we may end up with:
if (doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM") != null
&& doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0) != null {
Node searchResultNode = doc.getDocumentElement().getElementsByTagName("SEARCH-RESULT-ITEM").item(0);
}
Doing this reduces the number of IF statements from 3 to 1, and eliminates a redundant null check.
There is no safe dereference in Java.
It's generally bad practice to toss nulls around and Optional class may come to rescue as well ass checkNotNull at the beginning of the method, but nothing as fancy as Groovy one-liners.
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?