Multiple null checks in Java 8
JavaLambdaJava 8Java StreamOptionalJava Problem Overview
I have the below code which is bit ugly for multiple null checks.
String s = null;
if (str1 != null) {
s = str1;
} else if (str2 != null) {
s = str2;
} else if (str3 != null) {
s = str3;
} else {
s = str4;
}
So I tried using Optional.ofNullable
like below, but its still difficult to understand if someone reads my code. what is the best approach to do that in Java 8.
String s = Optional.ofNullable(str1)
.orElse(Optional.ofNullable(str2)
.orElse(Optional.ofNullable(str3)
.orElse(str4)));
In Java 9, we can use Optional.ofNullable
with OR
, But in Java8 is there any other approach ?
Java Solutions
Solution 1 - Java
You may do it like so:
String s = Stream.of(str1, str2, str3)
.filter(Objects::nonNull)
.findFirst()
.orElse(str4);
Solution 2 - Java
How about ternary conditional operator?
String s =
str1 != null ? str1 :
str2 != null ? str2 :
str3 != null ? str3 : str4
;
Solution 3 - Java
You can also use a loop:
String[] strings = {str1, str2, str3, str4};
for(String str : strings) {
s = str;
if(s != null) break;
}
Solution 4 - Java
Current answers are nice but you really should put that in a utility method:
public static Optional<String> firstNonNull(String... strings) {
return Arrays.stream(strings)
.filter(Objects::nonNull)
.findFirst();
}
That method has been in my Util
class for years, makes code much cleaner:
String s = firstNonNull(str1, str2, str3).orElse(str4);
You can even make it generic:
@SafeVarargs
public static <T> Optional<T> firstNonNull(T... objects) {
return Arrays.stream(objects)
.filter(Objects::nonNull)
.findFirst();
}
// Use
Student student = firstNonNull(student1, student2, student3).orElseGet(Student::new);
Solution 5 - Java
I use a helper function, something like
T firstNonNull<T>(T v0, T... vs) {
if(v0 != null)
return v0;
for(T x : vs) {
if (x != null)
return x;
}
return null;
}
Then this kind of code can be written as
String s = firstNonNull(str1, str2, str3, str4);
Solution 6 - Java
A solution which can be applied to as many element as you want can be :
Stream.of(str1, str2, str3, str4)
.filter(Object::nonNull)
.findFirst()
.orElseThrow(IllegalArgumentException::new)
You could imagine a solution like below, but the first one ensures non nullity
for all of the elements
Stream.of(str1, str2, str3).....orElse(str4)
Solution 7 - Java
You can also lump up all the Strings into an array of String then do a for loop to check and break from the loop once it's assigned. Assuming s1, s2, s3, s4 are all Strings.
String[] arrayOfStrings = {s1, s2, s3};
s = s4;
for (String value : arrayOfStrings) {
if (value != null) {
s = value;
break;
}
}
Edited to throw in condition for default to s4 if none is assigned.
Solution 8 - Java
Method based and simple.
String getNonNull(String def, String ...strings) {
for(int i=0; i<strings.length; i++)
if(strings[i] != null)
return s[i];
return def;
}
And use it as:
String s = getNonNull(str4, str1, str2, str3);
It's simple to do with arrays and looks pretty.
Solution 9 - Java
If you use Apache Commons Lang 3 then it can be written like this:
String s = ObjectUtils.firstNonNull(str1, str2, str3, str4);
Use of ObjectUtils.firstNonNull(T...)
was taken from this answer. Different approaches were also presented in related question.
Solution 10 - Java
Using of a for loop will be the most suitable solution, as all beginner and experienced developers have enough knowledge of Loops. It's quite simple, first make an array, and then check the entries one by one. If any nonNull string found then stop the loop, and proceed to the results.
String[] myData = {s1, s2, s3, s4};
String s = null;
for (String temp : myData) {
if (temp != null) {
s = temp;
break;
}
}
Now you can track the nonNull value of the string, or can check if all strings were null, by using the below code.
if(s != null)
System.out.println(s);
else
System.out.println("All Strings are null");