Java - Check Not Null/Empty else assign default value
Asked Answered
Y

11

118

I am trying to simplify the following code.

The basic steps that the code should carry out are as follows:

  1. Assign String a default value
  2. Run a method
  3. If the method returns a null/empty string leave the String as default
  4. If the method returns a valid string set the String to this result

A Simple example would be:

    String temp = System.getProperty("XYZ");
    String result = "default";
    if(temp != null && !temp.isEmpty()){
        result = temp;
    }

I have made another attemp using a ternary operator:

    String temp;
    String result = isNotNullOrEmpty(temp = System.getProperty("XYZ")) ? temp : "default";

The isNotNullOrEmpty() Method

 private static boolean isNotNullOrEmpty(String str){
    return (str != null && !str.isEmpty());
}

Is it possible to do all of this in-line? I know I could do something like this:

String result = isNotNullOrEmpty(System.getProperty("XYZ")) ? System.getProperty("XYZ") : "default";

But I am calling the same method twice. I would be something like to do something like this (which doesn't work):

String result = isNotNullOrEmpty(String temp = System.getProperty("XYZ")) ? temp : "default";

I would like to initialize the 'temp' String within the same line. Is this possible? Or what should I be doing?

Thank you for your suggestions.

Tim

Yorick answered 14/7, 2015 at 16:27 Comment(1)
System.getProperty("XYZ", "default")Etruscan
W
137

If using JDK 9 +, use Objects.requireNonNullElse(T obj, T defaultObj)

Wreckful answered 15/11, 2019 at 14:45 Comment(3)
Great method, finally we got it. It's a shame it does not do automatic int to long casting.Mayfield
but be aware that this method will throw a NPE if both arguments are null (can be desired, or not)Hemmer
'Objects.requireNonNullElse' is a good method for the null-case, but it doesn't consider the empty case like the questioner mentioned. I'd suggest the StringUtils.defaultIfBlank() or defaultIfEmpty() method from apache commons. If you want to check even more objects before the default is applied you could use: StringUtils.firstNonEmpty() or firstNonBlank() (ie. "StringUtils.firstNonEmpty(System.getProperty("XYZ"), System.getProperty("ABC"), "default")"Abhenry
H
104

Use Java 8 Optional (no filter needed):

public static String orElse(String defaultValue) {
  return Optional.ofNullable(System.getProperty("property")).orElse(defaultValue);
}
Harwell answered 14/7, 2015 at 16:36 Comment(6)
Optionals should not be created for flow control within a method. This is called out as an anti-pattern by the developers who built Optional. youtube.com/watch?amp=&v=Ej0sss6cq14Towill
@RyanBurbidge, and the reason: You unnecessarily create an object in your simple method (Optional object).Ginn
@PAX, if that's the only reason you can avoid it by using Optional::orElseGet instead. I personally prefer the ternary operator since it's just as lazy and shorter.Displease
@RyanBurbidge, nice reference, thanks! Relevant part of the video: 27:44 - 30:00Cuprite
@Q8i of course, if you make an operation unnecessarily complicated, you want to max it out. As otherwise, you could simply use System.getProperty("property", defaultValue) that does the job without additional syntactic constructs.Etruscan
I don't know why this solution is so popular, it's quite verbose.Adriell
T
79

I know the question is really old, but with generics one can add a more generalized method with will work for all types.

public static <T> T getValueOrDefault(T value, T defaultValue) {
    return value == null ? defaultValue : value;
}
Terpsichorean answered 18/6, 2017 at 16:10 Comment(6)
Thanks shibashis. I still use this code and have a method for lots of object types! I will try with generics instead to simplify the code. Thank youYorick
@Cam1989: This doesn't answer the question you asked though, because it doesn't handle empty strings... it only deals with the value being null, not empty... if that's what you wanted, that's what you should have asked. This is a perfectly good solution to a different problem, but it is a solution to a different problem...Simla
it would meet the empty requirement by replacing "value == null" with "isNotNullOrEmpty(value)" and switching value and defaultValue in the ternary responsesVengeance
Careful! While the ternary operator itself is lazy, this solution isn't! Which means a call to myThing = getValueOrDefault(thing, new Thing()); will create and discard that new Thing() if thing is not null. You may want to adapt this function to take a lambda instead so you may do getValueOrDefault(thing, Thing::new) instead.Displease
@Displease Since Java 9, this functionality exist as standard API method: Objects.requireNonNullElse(T obj, T defaultObj), including a variant with lazy construction of the fallback, Objects.requireNonNullElseGet(T obj, Supplier<? extends T> supplier).Etruscan
not exactly, default value has to be non-null in the JDK version.Vienna
G
69

Use org.apache.commons.lang3.StringUtils

String emptyString = new String();    
result = StringUtils.defaultIfEmpty(emptyString, "default");
System.out.println(result);

String nullString = null;
result = StringUtils.defaultIfEmpty(nullString, "default");
System.out.println(result);

Both of the above options will print:

default

default

Gravesend answered 12/9, 2016 at 6:57 Comment(1)
There is also StringUtils.defaultIfBlank to provide a default if the string is null or blank (e.g. contains spaces only) : result = StringUtils.defaultIfBlank(emptyString, "default");.Sharpeared
P
44

You can use this method in the ObjectUtils class from org.apache.commons.lang3 library :

public static <T> T defaultIfNull(T object, T defaultValue)
Ptosis answered 8/10, 2018 at 12:13 Comment(1)
This checks for null, but not for empty Strings. It's better to use StringUtils.defaultIfBlank insteadCelesta
S
15

Sounds like you probably want a simple method like this:

public String getValueOrDefault(String value, String defaultValue) {
    return isNotNullOrEmpty(value) ? value : defaultValue;
}

Then:

String result = getValueOrDefault(System.getProperty("XYZ"), "default");

At this point, you don't need temp... you've effectively used the method parameter as a way of initializing the temporary variable.

If you really want temp and you don't want an extra method, you can do it in one statement, but I really wouldn't:

public class Test {
    public static void main(String[] args) {
        String temp, result = isNotNullOrEmpty(temp = System.getProperty("XYZ")) ? temp : "default";
        System.out.println("result: " + result);
        System.out.println("temp: " + temp);
    }

    private static boolean isNotNullOrEmpty(String str) {
        return str != null && !str.isEmpty();
    }
}
Simla answered 14/7, 2015 at 16:31 Comment(2)
@fge Lets say it is not case of System.getProperty() but some method which doesn't have this extra parameter for default value. Then trick will work, it is scalable.Elly
How did I make this so complicated!? Thank you very much! I have used the getValueOrDefault() method. Great answer.Yorick
G
3

With guava you can use

MoreObjects.firstNonNull(possiblyNullString, defaultValue);
Glendoraglendower answered 15/12, 2019 at 3:21 Comment(0)
V
2

This is the best solution IMHO. It covers BOTH null and empty scenario, as is easy to understand when reading the code. All you need to know is that .getProperty returns a null when system prop is not set:

String DEFAULT_XYZ = System.getProperty("user.home") + "/xyz";
String PROP = Optional.ofNullable(System.getProperty("XYZ"))
        .filter(s -> !s.isEmpty())
        .orElse(DEFAULT_XYZ);
Verbenia answered 2/6, 2020 at 18:25 Comment(0)
K
1

If you need to set not null value or return default value instead you can use simple generic method

private <T> T getIfNotNullOrElse(T input, T defaultValue) {
   return Optional.ofNullable(input).orElse(defaultValue);
}
Kalasky answered 30/3, 2022 at 12:17 Comment(1)
a bit more complicated than just return input != null ? input : defaultValue; and even worse than this answer (check the comments, mainly about anti-pattern) - it is creating an additional object (instance of Optional)Hemmer
S
0

In Java 9, if you have an object which has another object as property and that nested objects has a method yielding a string, then you can use this construct to return an empty string if the embeded object is null :

String label = Optional.ofNullable(org.getDiffusion()).map(Diffusion::getLabel).orElse("")

In this example :

  • org is an instance of an object of type Organism
  • Organism has a Diffusion property (another object)
  • Diffusion has a String label property (and getLabel() getter).

With this example, if org.getDiffusion() is not null, then it returns the getLabel property of its Diffusion object (this returns a String). Otherwise, it returns an empty string.

Sharpeared answered 29/10, 2020 at 15:15 Comment(0)
O
0

Tim,

It is worth notice that on C based languages the attribution is also an expression and returns a value that can be used on other expressions. So the attribution can be rewritten as:

String result = (result = System.getProperty("XYZ")) != null ? result : "default"

or, using your function:

String result = isNotNullOrEmpty(result = System.getProperty("XYZ")) ? result : "default"

The trick to write this code in one line is to reuse the variable result instead of create a new temp one, which will not work inside of expressions.

You end up with an extra attribution, but will not run the method twice.

Ostiole answered 21/9, 2023 at 15:50 Comment(2)
readability decrease just to avoid a local variable or, not even that, to avoid one additional line of code/statementHemmer
@user85421, I agree with you that it has impact on readability. My intention was just to clarify why it failed as originally asked. I had a situation where I had to put similar logic inside one expression to use it in a tool.Ostiole

© 2022 - 2025 — McMap. All rights reserved.