207

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?

fastcodejava
  • 39,895
  • 28
  • 133
  • 186

11 Answers11

254

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;
}
Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
  • 63
    Note that Collections.emptyList() will avoid allocating an extra object (IIRC). – Jon Skeet Feb 12 '10 at 06:31
  • 8
    @Jon: I have always asked my self, what was the use of that `emptyList` http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collections.html#emptyList() What's IIRC? – OscarRyz Feb 12 '10 at 06:34
  • 14
    IIRC = "If I recall correctly". And yes, there is a singleton instance that is returned for all calls to Collections.emptyList(). – ColinD Feb 12 '10 at 06:40
  • This ... doesn't actually answer the question. Why is it accepted answer? – Christopher Wirt Apr 30 '15 at 21:34
  • 3
    @ChristopherWirt because it does answer the question :D – Tarik Dec 29 '15 at 15:16
  • Very cool example and direct. Only one tip. Both: EMPTY_LIST and emptyList() allocate one new instance. – Marcelo Rebouças Jan 06 '16 at 17:00
  • One thing to keep in mind though with `Collections.emptyList()`, the list is immutable, you can add any items to it. If you are just reading from the list, then this is fine, but if you want to add items you will need a new list object. IIRC if you do try to add to a `Collections.emptyList()`, the error message isn't the most helpful. – thecoshman Aug 16 '16 at 16:28
  • You can always use `commons-lang`'s `ArrayUtil` class. See [nullToEmpty](https://commons.apache.org/proper/commons-lang/javadocs/api-3.4/org/apache/commons/lang3/ArrayUtils.html#nullToEmpty(java.lang.Object[])) methods. – sdc Aug 24 '16 at 18:33
  • 1
    Both `Collections.emptyList` and `Collections.EMPTY_LIST` return `public static final List EMPTY_LIST = new EmptyList();` – sdc Aug 24 '16 at 21:14
  • Instead of Collections.emptyList() and Collectiosn.EMPTY_LIST, could it be also OK to return a new ArrayList with zero capacity? – Roberto Linares Oct 03 '16 at 23:16
  • @RobertoLinares that's technically fine but if you have no plans to add items to the list it's more efficient to use one of the options from Collections. Going back to the original question, the intention here is to avoid hitting a NullPointerException so making a brand new List wouldn't benefit you. – TastyWheat Jan 06 '23 at 18:13
104

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 3
    I would change the Iterable list parameter to Iterable iterable, as not every iterable is a list. – Lombo Feb 12 '10 at 06:35
  • Be careful using this method: because of use of Collections class, the use of this method involve your list te be immutable – Tanorix Apr 26 '17 at 16:34
  • @tanorix: In what way? – Jon Skeet Apr 26 '17 at 16:42
  • @JonSkeet you can see that emptyList() of Collections class return an immutable list : https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#emptyList-- so if the user do not want to have his list immutable it can be problematic – Tanorix Apr 27 '17 at 09:14
  • @tanorix: But the point of this question is about *iterating* over the returned value. That doesn't modify it. That's why the return type of `emptyIfNull` is `Iterable` - there's the unfortunate `remove` method on `Iterator`, but that's the only mutable aspect of it (and if you've got an empty collection, why are you trying to remove anything from it?) It's not clear what you're objecting to here. – Jon Skeet Apr 27 '17 at 09:28
41

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.

Fred Pym
  • 2,149
  • 1
  • 20
  • 29
  • 2
    Will work though creates unnecessary list object. A CollectionUtils.ifNotEmpty may be more verbose but more efficient and faster. Not that it would matter much... – Lawrence Aug 29 '17 at 10:07
  • 2
    In 2017 I would expect List.emptyIfNull(list1) – Dima Dec 04 '17 at 20:37
  • 5
    @Lawrence, the method doesn't create new list objects, it uses `Collections.emptyList()` internally, which in its turn always returns the same preallocated empty unmodifiable list. – Yoory N. Feb 27 '18 at 06:33
  • What if you call myobject.getCompanies().getAddresses() and both return a List and both can be null? – powder366 Jun 28 '20 at 13:42
14

With Java 8 Optional:

for (Object object : Optional.ofNullable(someList).orElse(Collections.emptyList())) {
    // do whatever
}
holmis83
  • 15,922
  • 5
  • 82
  • 83
  • 2
    Its more verbose than simple ternary operator like `someList != null ? someList : Collections.emptyList()` and also creates and immediately throws away an instance of `Optional` object. – Yoory N. Feb 27 '18 at 06:44
  • 7
    how are these monster lines more elegant than a simple if(someList==null) statement. Let's write a bank application in one line... – Andreas Panagiotidis Nov 09 '18 at 08:55
12

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;
}
100rabh
  • 142
  • 9
sdc
  • 2,603
  • 1
  • 27
  • 40
8

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.

Lombo
  • 11,847
  • 2
  • 20
  • 27
4

I have modified the above answer, so you don't need to cast from Object

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

and then simply call the List by

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

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

Haris Iltifat
  • 534
  • 5
  • 16
3

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

Jacob Briscoe
  • 252
  • 1
  • 8
1

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().

Nico de Wet
  • 319
  • 2
  • 12
0

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>
Swadeshi
  • 1,596
  • 21
  • 33
-5
for (Object object : someList) {

   // do whatever
}  throws the null pointer exception.
timgeb
  • 76,762
  • 20
  • 123
  • 145