コレクションを繰り返し処理する必要があるたびに、for-eachループの繰り返しが始まる直前に、nullをチェックすることになります。このような:
if( list1 != null ){
for(Object obj : list1){
}
}
「if」ブロックの書き込みを回避できるように、より短い方法がありますか?注:私はJava 5を使用していますが、しばらくの間は使用できなくなります。
正しい答えは、それを短くする方法がないということだと思います。コメントにあるようなテクニックはいくつかありますが、私はそれらを使用しているとは思いません。これらの手法を使用するよりも、「if」ブロックを記述する方が良いと思います。そして、はい..誰もが再び言及する前に:)「理想的に」コードは、リストがnullにならないように設計されるべきです。
可能であれば、コレクションが最初にnull
にならないようにコードを設計する必要があります。
null
コレクションは悪い習慣です(このため)。代わりに空のコレクションを使用する必要があります。 (例: Collections.emptyList()
)
または、Iterable
を実装し、コレクションを受け取り、null
コレクションを処理するラッパークラスを作成できます。
その後、foreach(T obj : new Nullable<T>(list1))
と書くことができます
public <T extends Iterable> T nullGuard(T item) {
if (item == null) {
return Collections.EmptyList;
} else {
return item;
}
}
あなたが書くことができるでしょう
for (Object obj : nullGuard(list)) {
...
}
もちろん、これは本当に複雑さを他の場所に移動させるだけです。
すでに2017年であり、現在使用できるのは Apache Commons Collections4
使用法:
for(Object obj : CollectionUtils.emptyIfNull(list1)){
// Do your stuff
}
Java 8には、Java.util.Optional
およびifPresent
-メソッドを使用した別のソリューションがあります。
Optional.ofNullable(list1).ifPresent(l -> l.forEach(item -> {/* do stuff */}));
したがって、正確な問題の解決策ではありませんが、ワンライナーであり、おそらくよりエレガントです。
public static <T> Iterable<T> emptyIfNull(Iterable<T> iterable) {
return iterable == null ? Collections.<T>emptyList() : iterable;
}
次に使用します:
for (Object object : emptyIfNull(someList)) { ... }
Apache Commons
for (String code: ListUtils.emptyIfNull(codes)) {
}
Google Guava
for (String code: Optional.of(codes).get()) {
}
どのくらい短くしたいですか?余分な2行だけで、明確で簡潔なロジックです。
あなたが決定する必要があるより重要なことは、null
が有効な値であるかどうかです。それらが有効でない場合は、発生しないようにコードを記述する必要があります。この場合、この種のチェックは必要ありません。 foreach
ループの実行中に例外が発生した場合、それはコードのどこかにバグがあることを示しています。
1)list1がクラスのメンバーである場合は、コンストラクターでリストを作成し、リストが空であるにもかかわらずnullでないようにします。
2)for(Object obj:list1!= null?list1:new ArrayList())