fastcodejava
fastcodejava

Reputation: 41087

Null check in an enhanced for loop

What is the best way to guard against null in a for loop in Java?

This seems ugly :

if (someList != null) {
    for (Object object : someList) {
        // do whatever
    }
}

Or

if (someList == null) {
    return; // Or throw ex
}
for (Object object : someList) {
    // do whatever
}

There might not be any other way. Should they have put it in the for construct itself, if it is null then don't run the loop?

Upvotes: 215

Views: 232963

Answers (12)

jspek
jspek

Reputation: 446

Using only Java here is an idea:

List<SomeType> someList= Objects.requireNonNullElse(listSource, new ArrayList<>());
for(var someElement: someList)){
  //...           
}

There are all sorts of variations to this approach. For example do you need someList to be immutable if empty? Then instead of an new ArrayList<>() you can use List.of(). This is just an example, feel free to use whichever data structure is best.

Upvotes: 0

Haris Iltifat
Haris Iltifat

Reputation: 534

I have modified another answer so you don't need to cast as an Object:

public static <T> List<T> safeClient( List<T> other ) {
            return other == null ? Collections.EMPTY_LIST : other;
}

Then simply call the List with:

for (MyOwnObject ownObject : safeClient(someList)) {
    // do whatever
}

Explanation: MyOwnObject: If List<Integer> then MyOwnObject will be an Integer in this case.

Upvotes: 4

sdc
sdc

Reputation: 3041

Use ArrayUtils.nullToEmpty from the commons-lang library for Arrays

for( Object o : ArrayUtils.nullToEmpty(list) ) {
   // do whatever 
}

This functionality exists in the commons-lang library, which is included in most Java projects.

// ArrayUtils.nullToEmpty source code 
public static Object[] nullToEmpty(final Object[] array) {
    if (isEmpty(array)) {
        return EMPTY_OBJECT_ARRAY;
    }
    return array;
}

// ArrayUtils.isEmpty source code
public static boolean isEmpty(final Object[] array) {
    return array == null || array.length == 0;
}

This is the same as the answer given by @OscarRyz, but for the sake of the DRY mantra, I believe it is worth noting. See the commons-lang project page. Here is the nullToEmpty API documentation and source

Maven entry to include commons-lang in your project if it is not already.

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
</dependency>

Unfortunately, commons-lang doesn't provide this functionality for List types. In this case you would have to use a helper method as previously mentioned.

public static <E> List<E> nullToEmpty(List<E> list)
{
    if(list == null || list.isEmpty())
    {
        return Collections.emptyList();
    }
    return list;
}

Upvotes: 13

Swadeshi
Swadeshi

Reputation: 1672

Use, CollectionUtils.isEmpty(Collection coll) method which is Null-safe check if the specified collection is empty.

for this import org.apache.commons.collections.CollectionUtils.

Maven dependency

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>

Upvotes: 0

holmis83
holmis83

Reputation: 16624

With Java 8 Optional:

for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) {
    // do whatever
}

Upvotes: 15

Fred Pym
Fred Pym

Reputation: 2329

It's already 2017, and you can now use Apache Commons Collections4

The usage:

for(Object obj : ListUtils.emptyIfNull(list1)){
    // Do your stuff
}

You can do the same null-safe check to other Collection classes with CollectionUtils.emptyIfNull.

Upvotes: 45

Jacob Briscoe
Jacob Briscoe

Reputation: 252

For anyone uninterested in writing their own static null safety method you can use: commons-lang's org.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object). For example:

    for (final String item : 
    (List<String>)ObjectUtils.defaultIfNull(items, Collections.emptyList())) { ... }

ObjectUtils.defaultIfNull JavaDoc

Upvotes: 3

user6315386
user6315386

Reputation: 1

for (Object object : someList) {

   // do whatever
}  throws the null pointer exception.

Upvotes: -5

Nico de Wet
Nico de Wet

Reputation: 334

Another way to effectively guard against a null in a for loop is to wrap your collection with Google Guava's Optional<T> as this, one hopes, makes the possibility of an effectively empty collection clear since the client would be expected to check if the collection is present with Optional.isPresent().

Upvotes: 1

OscarRyz
OscarRyz

Reputation: 199244

You should better verify where you get that list from.

An empty list is all you need, because an empty list won't fail.

If you get this list from somewhere else and don't know if it is ok or not you could create a utility method and use it like this:

for( Object o : safe( list ) ) {
   // do whatever 
 }

And of course safe would be:

public static List safe( List other ) {
    return other == null ? Collections.EMPTY_LIST : other;
}

Upvotes: 257

Jon Skeet
Jon Skeet

Reputation: 1501153

You could potentially write a helper method which returned an empty sequence if you passed in null:

public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
    return iterable == null ? Collections.<T>emptyList() : iterable;
}

Then use:

for (Object object : emptyIfNull(someList)) {
}

I don't think I'd actually do that though - I'd usually use your second form. In particular, the "or throw ex" is important - if it really shouldn't be null, you should definitely throw an exception. You know that something has gone wrong, but you don't know the extent of the damage. Abort early.

Upvotes: 106

Lombo
Lombo

Reputation: 12235

If you are getting that List from a method call that you implement, then don't return null, return an empty List.

If you can't change the implementation then you are stuck with the null check. If it should't be null, then throw an exception.

I would not go for the helper method that returns an empty list because it may be useful some times but then you would get used to call it in every loop you make possibly hiding some bugs.

Upvotes: 8

Related Questions