Arrays.asList()対Collections.singletonList()


138

1つの項目を含むリストを作成するために、Collections.singletonList(something)よりもArrays.asList(something)を使用することには利点(または大きな違い)がありますか?後者は、返されるリストも不変にします。


8
あなたはグアバのものImmutableList.of()Lists.newArrayList()一緒に投げることもできます。
biziclop 2014

これとは別に、Collections.singletonList()が原因で、後でダウンストリームで変更されるリストがメソッドから返されると問題が発生しました。
ハワードグリンバーグ

1
Java 10には真の不変リストがあります:stackoverflow.com/a/52536126/1216775
akhil_mittal

回答:


207

Collections.singletonList(something)不変ですがArrays.asList(something)List、ListとArrayがヒープで結合されるArrayの固定サイズ表現です。

Arrays.asList(something)Listと結合された配列の両方に反映される、非構造的な変更を許可します。UnsupportedOperationException特定のインデックスの要素を設定できますが、要素の追加、削除をスローします。

リストに加えられた変更はで返さCollections.singletonList(something)になりますUnsupportedOperationException

また、によって返されるリストの容量は、バッキングされた配列のサイズとは異なり、Collections.singletonList(something)常に1にArrays.asList(something)なります。


63

シングルトンリストは配列に裏打ちされておらず、その1つの項目への参照があるだけです。おそらく、必要なメモリが少なくなり、作成するリストの数によってはかなりの量になる可能性があります。


このメモリ効率ポイントを裏付けるリンクまたはコードはありますか?このArrays.asList(ONLY_ONE_OBJECT)をコードベース全体に広範に記述していて、Collections.singletonList()で置き換えるとメモリ効率が向上するかどうかを知りたいですか?
Rahul Saini、


13

このメソッドArrays.asListは、指定された配列に基づく固定サイズのリストを返します。このメソッドは、拡張されていないプライベートなネストされた静的クラスArrayListあるインスタンスを返します。この静的クラスは、いくつかのメソッドの実装などを提供しますが、それを呼び出すと、それ自体の実装はなく、からスローされるfromメソッドが呼び出されます。AbstractListjava.util.ArrayListset, indexOf, forEach, replaceAlladdAbstractListjava.lang.UnsupportedOperationException

Collections.singletonList戻り不変のリスト指定されたオブジェクトだけを含有し、それは同様にシリアライズ可能です。

余談ですが、不変のリストCollections.unmodifiableListでは、指定されたリストの変更不可能なビューを返す、一般的に使用されます。

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);     
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

変更不可能なビューコレクションは、変更不可能なコレクションであり、バッキングコレクションのビューでもあります。バッキングコレクションへの変更は引き続き可能であることに注意してください。変更が発生した場合は、変更不可能なビューから表示できます。

Java 10以降では、真の不変リストを使用できます。本当に変更不可能なリストを取得するには、2つの方法があります。

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); これら2つの変数のいずれかが使用されている場合、値は「Apple」であり、「Apricot」ではありません。

あたりとして、ドキュメントJavaの10

staticファクトリメソッドは、変更不可能なリストを作成するための便利な方法を提供します。これらのメソッドによって作成されたListインスタンスには、次の特性があります。List.ofList.copyOf

  1. それらは変更できません。要素を追加、削除、または置換することはできません。リストでミューテーターメソッドを呼び出すと、常に UnsupportedOperationExceptionスローされます。ただし、含まれる要素自体が変更可能である場合、これによりリストの内容が変更されているように見えることがあります。
  2. null要素は許可されません。null要素でそれらを作成しようとすると、になりますNullPointerException
  3. すべての要素が直列化可能であれば、それらは直列化可能です。
  4. リスト内の要素の順序は、指定された引数、または指定された配列内の要素の順序と同じです。
  5. 彼らはvalue-basedです。呼び出し元は、返されたインスタンスのIDについて想定しないでください。ファクトリは、新しいインスタンスを作成したり、既存のインスタンスを再利用したりできます。したがって、これらのインスタンスでのID依存操作(参照の等価性(==)、IDハッシュコード、および同期)は信頼性が低く、回避する必要があります。
  6. これらは、[シリアル化されたフォーム]ページで指定されているとおりにシリアル化されます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.