拡張されたforループでのnullチェック


172

Javaのforループでnullを防ぐ最善の方法は何ですか?

これは醜いようです:

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

または

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

他に方法はないかもしれません。彼らはforそれ自体を構成体に入れるべきでした、それがnullの場合はループを実行しないでください?


2
あなたはおそらくNPEを投げた方がいいでしょう。null空のコレクションと同じではありません。
トムホーティン-タックライン

6
@GregMattes 2月の質問は10月の質問と重複していますか?
Val

1
Collections.nonNullElementsIn(...)を使用する必要があるだけです
。stackoverflow.com/ a

回答:


227

そのリストをどこから取得するかをよりよく確認する必要があります。

空のリストは失敗しないので、空のリストで十分です。

他の場所からこのリストを取得し、それが問題ないかどうかわからない場合は、ユーティリティメソッドを作成して次のように使用できます。

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

そしてもちろんsafe

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

57
Collections.emptyList()は、追加のオブジェクト(IIRC)の割り当てを回避することに注意してください。
Jon Skeet

7
@ジョン:私はいつも自分自身に尋ねてきました。そのemptyList java.sun.com/j2se/1.5.0/docs/api/java/util/の用途は 何でしたか…IIRCとは何ですか?
OscarRyz 2010

11
IIRC =「正しく思い出せば」。はい、Collections.emptyList()へのすべての呼び出しに対して返されるシングルトンインスタンスがあります。
ColinD 2010

これは実際には質問の答えにはなりません。なぜそれは答えを受け入れたのですか?
Christopher Wirt 2015

1
@ChristopherWirtは質問に答えるため:D
Tarik

100

nullを渡した場合に空のシーケンスを返すヘルパーメソッドを作成する可能性があります。

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

次に使用します:

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

私は実際にそうするつもりはないと思います-私は通常あなたの2番目のフォームを使います。特に、「or throw ex」は重要です。本当にnullにしてはいけない場合は、必ず例外をスローする必要があります。あなたは何かがうまくいっていないことを知っていますが、被害の程度を知りません。早く打ち切る。


3
すべての反復可能オブジェクトがリストであるとは限らないため、Iterable <T>リストパラメータをIterable <T> iterableに変更します。
ロンボ

このメソッドの使用には注意が必要です
。Collections

@tanorix:どのように?
ジョンスキート2017

@JonSkeetを実行すると、CollectionsクラスのemptyList()が不変のリストを返すことがわかります:docs.oracle.com/javase/8/docs/api/java/util/…ユーザーが自分のリストを不変にしたくない場合は、問題がある
Tanorix 2017

@tanorix:しかし、この質問のポイントは、戻り値を反復することです。それはそれを変更しません。そのため、の戻り値の型emptyIfNullIterable<T>-に不幸なremoveメソッドがIterator<T>ありますが、それが唯一の変更可能な側面です(そして、空のコレクションがある場合、なぜそこから何かを削除しようとしているのですか?)それはあなたが何を明確にしていないのですか?ここに反対する。
Jon Skeet 2017

29

すでに2017年です。ApacheCommons Collections4を使用できます。

使い方:

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

を使用して、他のコレクションクラスに対して同じnullセーフチェックを実行できますCollectionUtils.emptyIfNull


2
動作しますが、不要なリストオブジェクトを作成します。CollectionUtils.ifNotEmptyは、より詳細になる可能性がありますが、より効率的で高速です。それはそれほど重要ではない...
ローレンス

2
2017年には、List.emptyIfNull(list1)を期待します
Dima

3
@Lawrence、このメソッドは新しいリストオブジェクトを作成せず、Collections.emptyList()内部的に使用します。このメソッドは、常に同じ割り当て済みの空の変更不可能なリストを常に返します。
Yoory N.

myobject.getCompanies()。getAddresses()を呼び出し、両方がリストを返し、両方がnullになる可能性がある場合はどうなりますか?
パウダー366

9

Java 8の場合Optional

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

1
のような単純な3項演算子よりも詳細でsomeList != null ? someList : Collections.emptyList()Optionalオブジェクトのインスタンスを作成してすぐに破棄します。
Yoory N.

2
これらのモンスターラインは、単純なif(someList == null)ステートメントよりもエレガントです。銀行のアプリケーションを1行で記述しましょう...
Andreas Panagiotidis

8

配列ArrayUtils.nullToEmptycommons-langライブラリから使用

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

この機能commons-langは、ほとんどのJavaプロジェクトに含まれているライブラリに存在します。

// 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;
}

これは@OscarRyzの回答と同じですが、DRYのマントラのために、注目に値すると思います。参照コモンズ・ラングのプロジェクトページを。ここにnullToEmptyAPI ドキュメントソースがあります

commons-langプロジェクトに含めるMavenエントリ(まだ含まれていない場合)。

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

残念ながら、commons-langはこのListタイプの機能を提供していません。この場合、前述のようにヘルパーメソッドを使用する必要があります。

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

7

List実装したメソッド呼び出しからそれを取得している場合はnull、を返さず、空を返しますList

実装を変更できない場合、nullチェックに行き詰まります。そうでない場合はnull、例外をスローします。

空のリストを返すヘルパーメソッドを使用しない場合があります。これは、場合によっては便利かもしれませんが、すべてのループで呼び出しに慣れ、バグを隠してしまう可能性があります。


4

上記の回答を変更したので、Objectからキャストする必要はありません

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

次に単にリストを呼び出す

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

説明:MyOwnObject:この場合List<Integer>、MyOwnObjectはIntegerになります。


1

forループでnullを効果的に防ぐ別の方法は、コレクションをGoogle GuavaでラップするOptional<T>ことです。これにより、コレクションが存在するかどうかをクライアントが確認することが期待されるため、コレクションが実質的に空の可能性が明らかになりますOptional.isPresent()


1

独自の静的null安全メソッドを作成することに関心がない人は、commons-lang'sを使用できますorg.apache.commons.lang.ObjectUtils.defaultIfNull(Object, Object)。例えば:

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

ObjectUtils.defaultIfNull JavaDoc


私にとって、この答えは最もエレガントです
Truong Nguyen

0

CollectionUtils.isEmpty(Collection coll)指定したコレクションが空かどうかをヌルセーフチェックするメソッドを使用します。

このためimport org.apache.commons.collections.CollectionUtils

Mavenの依存関係

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

-4
for (Object object : someList) {

   // do whatever
}  throws the null pointer exception.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.