Java 改善の章 (36) -----Java コレクションの詳細 (2): asList の欠陥

黄舟
リリース: 2017-02-11 10:33:48
オリジナル
1392 人が閲覧しました

実際の開発プロセスでは、配列をリストに変換するために asList を使用することがよくあります。このメソッドは非常に便利ですが、asList メソッドにはいくつかの欠点があります。

1. 配列をリストに変換するために基本的なデータ型を使用しないでください。

本ベース 8 つの基本的な配列型をリストに変換すると、さらに風味豊かな欠陥が発生します。まず、次のプログラムを見てください。 re

public static void main(String[] args) {
        int[] ints = {1,2,3,4,5};
        List list = Arrays.asList(ints);
        System.out.println("list'size:" + list.size());
    }
    ------------------------------------
    outPut:
    list'size:1
ログイン後にコピー
プログラムの実行結果は、予想どおり 5 ではなく 1 です。状況はどうなっているでしょうか。まずソースコードを見てみましょう:

public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
ログイン後にコピー
ログイン後にコピー
asList で受け入れられるパラメーターは、基本的な可変長パラメーターであることがわかっています。これは、8 つの基本的な型をカスタマイズできないことを意味します。 asList として使用 パラメーターの場合、汎用パラメーターとして使用する場合は、対応するパッケージ化タイプを使用する必要があります。しかし、なぜこの場合何も問題が起こらなかったのでしょうか?このインスタンスはパラメータとして int 型の配列を使用し、配列は Java のオブジェクトであるため、ジェネリック化できます。したがって、この例ではエラーは発生しません。この例では int 型配列全体をジェネリック パラメーターとして使用しているため、asList 変換後の int リストは 1 つだけになります。以下の通り:

public static void main(String[] args) {
    int[] ints = {1,2,3,4,5};
    List list = Arrays.asList(ints);
    System.out.println("list 的类型:" + list.get(0).getClass());
    System.out.println("list.get(0) == ints:" + list.get(0).equals(ints));
}
--------------------------------------------
outPut:
list 的类型:class [I
list.get(0) == ints:true
ログイン後にコピー

この演算結果から、リスト内の要素が int 配列であることを完全に証明できます。これを理解すると、int を Integer に変更するという変更方法が一目瞭然になります。

public static void main(String[] args) {
        Integer[] ints = {1,2,3,4,5};
        List list = Arrays.asList(ints);
        System.out.println("list&#39;size:" + list.size());
        System.out.println("list.get(0) 的类型:" + list.get(0).getClass());
        System.out.println("list.get(0) == ints[0]:" + list.get(0).equals(ints[0]));
    }
    ----------------------------------------
    outPut:
    list&#39;size:5
    list.get(0) 的类型:class java.lang.Integer
    list.get(0) == ints[0]:true
ログイン後にコピー

>>>>>>Java の詳細 (2.1): asList を使用する場合は、基本データ型をパラメーターとして使用しないでください。

2. asList によって生成されたリストは操作できません

上記の例に少し変更を加えます:

public static void main(String[] args) {
        Integer[] ints = {1,2,3,4,5};
        List list = Arrays.asList(ints);
        list.add(6);
    }
ログイン後にコピー

この例は、asList がリストに変換する int の受け渡しに関するものです。この例はこれ以上に単純ですが、実行結果はどうなるでしょうか。予期した内容を入力します:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(Unknown Source)
    at java.util.AbstractList.add(Unknown Source)
    at com.chenssy.test.arrayList.AsListTest.main(AsListTest.java:10)
ログイン後にコピー

実行結果は UnsupportedOperationException 例外をスローします。 list は add メソッドをサポートしていません。これでは、リストが add メソッドをサポートしていないはずがないと憂鬱になります。 JDKの脳はブロックされていますか? asList のソースコードをもう一度見てみましょう:

public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }
ログイン後にコピー
ログイン後にコピー

. s パラメータを使用すると、新しい ArrayList が直接作成されます。ここでエラーは発生しないはずです。心配しないで、読み続けてください:

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable{
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

        ArrayList(E[] array) {
            if (array==null)
                throw new NullPointerException();
            a = array;
        }
        //.................
    }
ログイン後にコピー

これは ArrayList のソース コードです。ここから、この ArrayList が java.util.ArrayList ではなく、Array の内部クラスであることがわかります。この内部クラスには size、toArray、get、set、indexOf メソッドが用意されており、リストの結果を変更する add や delete などのメソッドは AbstractList 親クラスから継承されています。同時に、これらのメソッドも非常に奇妙なものです。 UnsupportedOperationException 例外を直接スローします。

public boolean add(E e) {
        add(size(), e);
        return true;
    }
    
    public E set(int index, E element) {
        throw new UnsupportedOperationException();
    }
    
    public void add(int index, E element) {
        throw new UnsupportedOperationException();
    }
    
    public E remove(int index) {
        throw new UnsupportedOperationException();
    }
ログイン後にコピー

これらのコードを通して、asList によって返されるリストはリストに見せかけた単なるリストであることがわかります。これにはリストの基本的な特性がありません (可変長)。リストは不変の長さのリストです。返されるリストは、渡されたパラメーターの配列と同じ長さのみです。したがって:

>>>>>>Java の詳細 (2.2): asList によって返されるリストを変更しようとしないでください。変更しないと、結果に苦しむことになります。

上記は Java 改善の章 (36) の内容です -----Java コレクションの詳細 (2): asList の欠陥 詳細については、PHP 中国語 Web サイト ( www.php.cn )!

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート