Java 9はリストの新しいファクトリーメソッドを導入しましたList.of
:
List<String> strings = List.of("first", "second");
以前のオプションと新しいオプションの違いは何ですか?つまり、これの違いは何ですか?
Arrays.asList(1, 2, 3);
この:
List.of(1, 2, 3);
Java 9はリストの新しいファクトリーメソッドを導入しましたList.of
:
List<String> strings = List.of("first", "second");
以前のオプションと新しいオプションの違いは何ですか?つまり、これの違いは何ですか?
Arrays.asList(1, 2, 3);
この:
List.of(1, 2, 3);
回答:
Arrays.asList
によって返されるリストList.of
が不変である一方で、変更可能なリストを返します。
List<Integer> list = Arrays.asList(1, 2, null);
list.set(1, 10); // OK
List<Integer> list = List.of(1, 2, 3);
list.set(1, 10); // Fails with UnsupportedOperationException
Arrays.asList
null要素List.of
は許可しますが、以下は許可しません。
List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException
contains
nullの場合の動作は異なります。
List<Integer> list = Arrays.asList(1, 2, 3);
list.contains(null); // Returns false
List<Integer> list = List.of(1, 2, 3);
list.contains(null); // Fails with NullPointerException
Arrays.asList
渡された配列のビューを返すため、配列への変更はリストにも反映されます。以下のためにList.of
これは本当ではありません。
Integer[] array = {1,2,3};
List<Integer> list = Arrays.asList(array);
array[1] = 10;
System.out.println(list); // Prints [1, 10, 3]
Integer[] array = {1,2,3};
List<Integer> list = List.of(array);
array[1] = 10;
System.out.println(list); // Prints [1, 2, 3]
List.contains(Object o)
のjavadocの: 『[...] NullPointerExceptionがスロー-指定された要素がnullで、このリストである場合には(オプション)null要素を許可しません』。または、インターフェースの長い紹介から、「コレクションの実装によっては、それらに含まれる可能性のある要素に制限がある」
List.of
がImmutableList
、実際の名前は非公開の実装の詳細にすぎません。それが公開されていて、誰かがList
再度キャストした場合、どこが違うのですか?またはを試行したときに例外をスローするArrays.asList
非パブリックList
実装を返すとの違い、またはによって返されるリストで変更がまったく許可されないのはどこですか?それはすべて、インターフェイスで指定されたコントラクトについてです。オプションのメソッドを備えたコレクションインターフェイスは、Java 1.2以降常に不純なOOPでした...add
remove
Collections.unmodifiableList
List
Arrays.asList
とList.of
JavaDocsと、Stuart Marks(またはその以前のバージョン)によるこの講演を参照してください。
次のコード例を使用します。
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
構造的に変更しようとするList.of
と、が発生しますUnsupportedOperationException
。これには、追加、設定、削除などの操作が含まれます。ただし、リスト内のオブジェクトの内容を変更することができるため(オブジェクトが不変でない場合)、リストは「完全に不変」ではありません。
これは、で作成された変更不可能なリストの運命と同じCollections.unmodifiableList
です。このリストのみが元のリストのビューであるため、元のリストを変更すると変更される可能性があります。
Arrays.asList
は完全に不変ではなく、に制限はありませんset
。
listOf.set(1, "a"); // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
同様に、(保持している場合)バッキング配列を変更すると、リストが変更されます。
構造的不変性には、防御的コーディング、同時実行性、およびセキュリティに関連する多くの副作用が伴いますが、この回答の範囲を超えています。
List.of
Java 1.5以降のコレクションではnull
、要素として使用できません。null
要素またはルックアップとして渡そうとすると、になりNullPointerException
ます。
以来Arrays.asList
1.2から収集(コレクション・フレームワーク)で、それができますnull
秒。
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
以来List.of
Javaの9に導入され、この方法で作成されたリストは、自分の(バイナリ)直列化形式を持ってきた、彼らは以前のJDKのバージョン(なしに非直列化することはできませんバイナリ互換)。ただし、たとえばJSONを使用して逆シリアル化できます。
Arrays.asList
内部的にを呼び出しnew ArrayList
、参照の不等式を保証します。
List.of
内部実装に依存します。返されるインスタンスは参照の等価性を持つことができますが、これは保証されていないため、それに依存することはできません。
asList1 == asList2; // false
listOf1 == listOf2; // true or false
リストのList.equals
作成方法やサポートする操作に関係なく、同じ要素が同じ順序で含まれている場合、リストは(を介して)等しいと言及する価値があります。
asList.equals(listOf); // true i.f.f. same elements in same order
リストの要素数List.of
が2以下の場合、要素は特殊な(内部)クラスのフィールドに格納されます。例は、2つの要素(部分的なソース)を格納するリストです。
static final class List2<E> extends AbstractImmutableList<E> {
private final E e0;
private final E e1;
List2(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
}
それ以外の場合は、と同様の方法で配列に格納されArrays.asList
ます。
List.of
フィールドベース(サイズ<2)の実装は、一部の操作でわずかに高速に実行されます。例としてsize()
、配列の長さをフェッチせずに定数を返すことができcontains(E e)
、反復オーバーヘッドを必要としません。
を介して変更不可能なリストを作成するList.of
ことも高速です。上記のコンストラクターを2つの参照割り当て(および要素の任意の量の1つ)と比較します。
Collections.unmodifiableList(Arrays.asList(...));
2つのリストとその他のオーバーヘッドを作成します。スペースの点では、UnmodifiableList
ラッパーといくつかのペニーを節約できます。結局、HashSet
同等の節約はより説得力があります。
結論時間:List.of
変更されないリストが必要なArrays.asList
場合、および変更可能なリストが必要な場合に使用します(上記を参照)。
Arrays.asList
完全に変更可能ではありません。asList.add(1);
をスローしUnsupportedOperationException
ます。
List.of
、人々が電話をかけたいと思うことがcontains
あり、NullPointerExceptionに驚かされることはありません。
List.ofとArrays.asListの違いを要約してみましょう
List.of
データセットが少なく、変更されていないArrays.asList
場合に最適に使用できますが、大規模で動的なデータセットの場合に最適に使用できます。
List.of
固定オーバーヘッドの観点からも要素ごとの観点からも、フィールドベースの実装があり、消費するヒープスペースが少ないため、オーバーヘッドスペースが非常に少なくて済みます。一方Arrays.asList
、初期化中にヒープ内により多くのオブジェクトが作成されるため、オーバーヘッド領域が増えます。
によって返されるコレクションList.of
は不変であり、したがってスレッドセーフですが、によって返されるコレクションArrays.asList
は変更可能であり、スレッドセーフではありません。(変更不可能なコレクションインスタンスは、通常、変更可能なコレクションインスタンスよりもはるかに少ないメモリを消費します。)
List.of
許可していないヌルながら要素をArrays.asList
可能にヌルの要素を。
Arrays.asList
対List.of
前者は文字通り配列単なるラッパーであることを考えると、。少なくともOpenJDKの実装では、オーバーヘッドが非常に小さいようです。実際、List.of
渡された配列のコピーを作成する必要があるため、配列自体がすぐにGCされる予定がない限り、List.of
メモリフットプリントが大幅に大きくなるように見えます。
List.of(x)
とList.of(x, y)
、彼らはすべての配列を割り当てていないため、より効率的である
List.of
メソッドが毎回新しいリストを返す必要がないことを忘れないでください。これらのリストには未指定のIDがあるため、JVMレベルでキャッシュ、重複排除、またはスカラー化が処理される可能性があります。このバージョンにない場合は、おそらく次のバージョンにあります。契約で許されています。対照的に、Array.asList
結果のリストは配列の可変ビューであり、すべての変化を双方向に反映するため、渡す配列のIDに依存します。
上記の回答とは別に、両方List::of
とArrays::asList
が異なる特定の操作があります。
+----------------------+---------------+----------+----------------+---------------------+
| Operations | SINGLETONLIST | LIST::OF | ARRAYS::ASLIST | JAVA.UTIL.ARRAYLIST |
+----------------------+---------------+----------+----------------+---------------------+
| add | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| addAll | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| clear | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| remove | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| removeAll | ❗️ | ❌ | ❗️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| retainAll | ❗️ | ❌ | ❗️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| replaceAll | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| set | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| sort | ✔️ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| remove on iterator | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| set on list-iterator | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+