可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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))
回答2:
public <T extends Iterable> T nullGuard(T item) {
if (item == null) {
return Collections.EmptyList;
} else {
return item;
}
}
would allow you to write
for (Object obj : nullGuard(list)) {
...
}
Of course, this really just moves the complexity elsewhere.
回答3:
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
回答4:
It's already 2017, and you can now use Apache Commons Collections4
The usage:
for(Object obj : CollectionUtils.emptyIfNull(list1)){
// Do your stuff
}
回答5:
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)) { ... }
回答6:
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.
回答7:
Apache Commons
for (String code: ListUtils.emptyIfNull(codes)) {
}
Google Guava
for (String code: Optional.of(codes).get()) {
}
回答8:
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.
回答9:
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())