web-dev-qa-db-ja.com

不変リストについて(Arrays.asList()で作成)

Java.util.Arrays.asList()を使用して配列からリストを作成する場合、リストは不変です。 List(またはSetまたはMap)の基本的な目的が動的なサイズであり、要素を自由に追加、削除できます。固定サイズのデータ​​構造が必要な場合は配列を使用し、動的データ構造が必要な場合はListまたはSetまたはMapなどを使用します。したがって、目的は何ですか不変のリストを持っているのですか?私は自分の割り当てに取り組んでいるときにこれに遭遇しました。

21
Venkat

Java.util.Arrays.asList()を使用して配列からリストを作成する場合、リストは変更可能です。

はい、いいえ:を呼び出すことにより、リストを変更できます

list.set(index, element);

ただし、リストは変更されない構造的に変更される場合があります。つまり、リストに要素を追加したり、リストから要素を削除したりすることはできません。その理由は、リストがまだ配列によって裏付けられており、配列のサイズが変更されない可能性があるためです。

固定サイズの可変コレクションが必要な場合は、Arrayを使用します

そして、それがここで重要なポイントです。配列はnota Collection です。 Arrays.asListメソッドは、主に「配列の世界」と「コレクションの世界」の間の「架け橋」として機能します。

Arrays.asListメソッドを使用すると、たとえば、Collectionを期待するメソッドにデータを渡すことができます。

// A method that expects a collection:
void process(List<String> strings) { ... }

void call()
{
    String array[] = new String[] { "A", "B", "C" };

    // Pass the array (as a list) to the method:
    process(Arrays.asList(array));
}

このアプリケーションケースには、配列から他のコレクションを作成することが含まれます。たとえば、配列があり、配列の要素を含むSetを作成する場合は、次のことができます。

String array[] = new String[] { "A", "B", "C" };
Set<String> set = new HashSet<String>();
for (String s : array) 
{
    set.add(s);
}

しかし、Arrays.asListメソッド、これはより便利に行うことができます:

Set<String> set = new HashSet<String>(Arrays.asList(array));

Arrays.asListメソッドは、いわば Collection#toArray メソッドの対応物であり、反対方向に機能します(ただし、このメソッドは通常、new配列、一方Arrays.asListメソッドは配列を「ラップ」し、Listのように見えるようにします)。

32
Marco13

Java.util.Arrays.asList()return new ArrayList<>(a);を呼び出しますが、このArrayListはAbstractListを拡張し、一部の実装をオーバーライドする配列のプライベートクラスです。したがって、Java.util.ArrayListの動作を期待するのは不公平です。 Java.util.AbstractListを調べると、add(E e)を呼び出すことができますが、他の多くのメソッドを呼び出せないことがわかります。したがって、現在の実装に従って、リストの下部に要素を追加することはできますが、リストの既存の構造を変更することはできません。

1
krmanish007

これは、クラスAbstractListadd()が原因で、Arrays Javaクラス(内部で使用されます)。このadd()メソッドは、Java.util.ArrayListで定義されているものと同じではなく、Java.util.Arrays$ArrayListのメソッドであることに注意してください。

配列には、jvmによってネイティブに提供される固定サイズのプロパティがあります。たとえ、Arrays.copyOf()がArrays.copyOf(arr, 10); //10 is the lengthのようにサイズを大きくして使用されている場合でも、元の配列はarr= int[]{1,2} // size is twoです。それは作成します 常に新しい配列 最終的にネイティブメソッドを呼び出すSystem.arraycopy()を使用します。

[静的void arraycopy(オブジェクトsrc、int srcPos、オブジェクトdest、int destPos、int長さ)]

上記のリストにはサイズ制限のみがあることに注意してください。本当に可変リストを不変にしたい場合は、Collections.unmodifiableList(mutableList);を使用してみてください。不変性はjvmで定義された概念ではなく、開発者の考えです。 https://stackoverflow.com/a/42071121/5620851 および https://stackoverflow.com/a/42138471/5620851 を参照してください

0
hi.nitish