web-dev-qa-db-ja.com

Collections.emptyList()と新しいインスタンス

実際には、 this のように空のリストを返すほうが良いでしょうか。

return Collections.emptyList();

または this :のように

return new ArrayList<Foo>();

それとも、返されたリストをどう処理するかに完全に依存していますか。

214
mre

主な違いは、 Collections.emptyList()不変リスト、つまり要素を追加できないリストを返すことです。 (Java 9で導入された List.of() も同様です。)

Collections.emptyList()List.of()は、が返されたリストを変更したいというまれなケースでは、そうではありません良い選択です。

不変のリストを返すことは、契約(ドキュメンテーション)が明示的に別の言い方をしていない限り、完全に(そして好ましい方法でさえ)うまくいくと言うでしょう。


さらに、emptyList()毎回の呼び出しで新しいオブジェクトを作成しないかもしれません

このメソッドの実装は、呼び出しごとに個別のListオブジェクトを作成する必要はありません。この方法を使用すると、同名のフィールドを使用するのと同程度のコストがかかる可能性があります。 (この方法とは異なり、このフィールドは型安全を提供しません。)

emptyListの実装は次のようになります。

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

つまり、空のリストを返すメソッドが頻繁に呼び出される場合は、この方法を使用すると、CPUとメモリの両方でわずかに優れたパフォーマンスが得られることさえあります。

267
aioobe

Java 5.0以降では、コンテナ内の要素の種類を指定できます。

Collections.<Foo>emptyList()

空のままの空のリストを返したい場合は、このアプローチを使用する必要があるという他の回答にも同意します。

46
Paul Jackson

Collections.emptyListは不変なので、2つのバージョンには違いがあるので、戻り値のユーザーを考慮する必要があります。

new ArrayList<Foo>を返すことは常にオブジェクトの新しいインスタンスを作成するのでそれに関連してそれはあなたにCollections.emptyListを使う理由を与えるかもしれない非常にわずかな追加費用があります。読みやすいという理由だけでemptyListを使うのが好きです。

25
Jeff Foster

でも慎重に。 Collections.emptyList()を返してからadd()やsmthのような変更を加えようとすると、UnsupportedOperationException()は不変オブジェクトを返すので、uはCollections.emptyList()を持ちます。

11
mrserfr

返されたリストが(リストが不変のため)変更されていない場合はCollections.emptyList()を使用します。それ以外の場合はオプション2を使用します。

Collections.emptyList()の利点は、毎回同じ静的インスタンスが返されるため、呼び出しごとにインスタンスの作成が行われないことです。

6
S73417H

返されたリストが絶対に変更されないようにしたい場合は、Collections.emptyList()を使用してください。これはemptyList()の呼び出しで返されるものです。

/**
 * The empty list (immutable). 
 */
public static final List EMPTY_LIST = new EmptyList();
2
Atul

与えられた答えはemptyList()が不変のListを返すという事実を強調しますが、代替を与えません。 ArrayList(int initialCapacity)の代わりにnew ArrayList<>(0)を返すコンストラクタnew ArrayList<>()特別な場合0も実行可能な解決策かもしれません:

/**
 * Shared empty array instance used for empty instances.
 */
private static final Object[] EMPTY_ELEMENTDATA = {};

[...]

/**
 * Constructs an empty list with the specified initial capacity.
 *
 * @param  initialCapacity  the initial capacity of the list
 * @throws IllegalArgumentException if the specified initial capacity
 *         is negative
 */
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {
        this.elementData = EMPTY_ELEMENTDATA;
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

(Java 1.8.0_72からのソース)

1
René