Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to avoid null check before the for-each loop iteration starts? [duplicate]

Every time I have to iterate over a collection I end up checking for null, just before the iteration of the for-each loop starts. Like this:

if( list1 != null ){
    for(Object obj : list1){

    }
}

Is there a shorter way, so that we can avoid writing the "if" block ? Note: I am using Java 5, and will be stuck with it for sometime.

like image 688
rk2010 Avatar asked May 20 '11 21:05

rk2010


People also ask

Does for-each loop check for NULL?

The question checks if the collection is null first before doing the for-each. Your link checks if the item in the collection is null.

Does for loop throws null pointer exception Java?

The following java segment will result a NullPointException, since the variable list is null, which is pass to the for-each loop. Include arr!= null expression could reduce code nesting. If you know that arr is not null already, would you like it to go through an extra useless null check?


10 Answers

If possible, you should design your code such that the collections aren't null in the first place.

null collections are bad practice (for this reason); you should use empty collections instead. (eg, Collections.emptyList())

Alternatively, you could make a wrapper class that implements Iterable and takes a collections, and handles a null collection.
You could then write foreach(T obj : new Nullable<T>(list1))

like image 77
SLaks Avatar answered Oct 19 '22 22:10

SLaks


public <T extends Iterable> T nullGuard(T item) {
  if (item == null) {
    return Collections.EmptyList;
  } else {
    return item;
  }
}

or, if saving lines of text is a priority (it shouldn't be)

public <T extends Iterable> T nullGuard(T item) {
  return (item == null) ? Collections.EmptyList : item;
}

would allow you to write

for (Object obj : nullGuard(list)) {
  ...
}

Of course, this really just moves the complexity elsewhere.

like image 23
Edwin Buck Avatar answered Oct 19 '22 23:10

Edwin Buck


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

The usage:

for(Object obj : CollectionUtils.emptyIfNull(list1)){
    // Do your stuff
}
like image 23
Fred Pym Avatar answered Oct 19 '22 22:10

Fred Pym


I guess the right answer is that: there is no way to make it shorter. There are some techniques such as the ones in the comments, but I don't see myself using them. I think it's better to write a "if" block than to use those techniques. and yes.. before anybody mentions it yet again :) "ideally" the code should be desgined such that list should never be a null

like image 33
rk2010 Avatar answered Oct 19 '22 22:10

rk2010


In Java 8 there is another solution available by using java.util.Optional and the ifPresent-method.

Optional.ofNullable(list1).ifPresent(l -> l.forEach(item -> {/* do stuff */}));

So, not a solution for the exact problem but it is a oneliner and possibly more elegant.

like image 36
wassgren Avatar answered Oct 19 '22 23:10

wassgren


Null check in an enhanced for loop

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

Then use:

for (Object object : emptyIfNull(someList)) { ... }
like image 38
gavenkoa Avatar answered Oct 19 '22 22:10

gavenkoa


Apache Commons

for (String code: ListUtils.emptyIfNull(codes)) {

}           

Google Guava

for (String code: Optional.of(codes).get()) {

}
like image 39
Kerem Baydoğan Avatar answered Oct 20 '22 00:10

Kerem Baydoğan


How much shorter do you want it to be? It is only an extra 2 lines AND it is clear and concise logic.

I think the more important thing you need to decide is if null is a valid value or not. If they are not valid, you should write you code to prevent it from happening. Then you would not need this kind of check. If you go get an exception while doing a foreach loop, that is a sign that there is a bug somewhere else in your code.

like image 22
unholysampler Avatar answered Oct 19 '22 22:10

unholysampler


1) if list1 is a member of a class, create the list in the constructor so it's there and non-null though empty.

2) for (Object obj : list1 != null ? list1 : new ArrayList())

like image 33
Chris Avatar answered Oct 19 '22 23:10

Chris


Another Java 8+ way would be to create a forEach method that does not crash when using a null value:

public static <T> void forEach(Iterable<T> set, Consumer<T> action) {
    if (set != null) {
        set.forEach(action);
    }
}

The usage of the own defined foreach is close to the native Java 8 one:

ArrayList<T> list = null;

//java 8+ (will throw a NullPointerException)
list.forEach(item -> doSomething(...) );

//own implementation
forEach(list, item -> doSomething(...) );
like image 24
Jacob van Lingen Avatar answered Oct 19 '22 23:10

Jacob van Lingen