4

さて、これは私には意味がありません....多分誰かが光を当てることができます. プリミティブ配列を ArrayLists に変換するために私が見つけた手法は次のとおりです。

arr = new ArrayList<String>(Arrays.asList(primitveArray));

これはうまくいきます。しかし、今日、これがどれほど効率的だったのか疑問に思い始めました。たまたま、パフォーマンスがより重要なコードを書いていたからです。過去に取り組んだ他のアプリケーションでそうであったため、ソース コードを調べることにしました。Arrays.asList()

私はこれを見つけました:

public static <T> List<T> asList(T... array) {
    return new ArrayList<T>(array);
}

そして、私は自分自身に言いました:「私はなんてばかだ、配列を ArrayList コンストラクターに渡すだけだArrayList<T>(T[] arr)、なぜ私はステップをスキップして、愚かな Arrays.asList を使用しないのですか?

だから私はこれを試します

arr = new ArrayList<T>(primitveArray)

私のコードで。しかし、突然ArrayList<T>(T[] arr)未定義です。なぜこれができるのか非常に混乱していますか?

4

6 に答える 6

5

But then suddenly ArrayList<T>(T[] arr) is undefined. I'm quite confused why this would be?

There are two classes named ArrayList:

  • one is a private static inner class of java.util.Arrays;
  • the other is java.util.ArrayList.

asList() uses the former. You are trying to use the latter. The two classes are unrelated, they just happen to share the same name.

It is important to note that java.util.Arrays.ArrayList does not copy the array. It provides a view onto it.

于 2012-05-25T17:01:24.317 に答える
2

だから私はこれを試してみますarr = new ArrayList<T>(primitveArray)

Tは一般的に型指定されたパラメーターであり、ArrayListをインスタンス化するときに使用することはできず、クラスまたはメソッドでの使用を宣言する場合にのみ使用できます。代わりに、コードを次のように変更します。

arr = Arrays.asList(primitveArray);

Arraysクラスで使用されるArrayListクラスは、コードで使用するArrayListクラスとは異なり、Arraysクラス自体で定義される内部クラスであり、Arrayを引数として取るコンストラクターを定義します。このクラスはプライベートであり、非パブリックコンストラクターを使用しているため、Arraysクラス自体の中でのみインスタンス化して使用できます。

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;
    }

...
于 2012-05-25T16:58:38.733 に答える
2

さて、この質問をした後、私はそれを理解しました。java.util.Arraysとは別のArrayListと呼ばれる静的ローカルクラスを適切に実装しますjava.util.ArrayList。紛らわしいことに、どちらもArrayListという名前ですが、asjava.util.Arrays.ArrayListは次のように宣言されています。

private static class ArrayList<E> extends AbstractList<E> implements
        List<E>, Serializable, RandomAccess

java.util.ArrayListとして宣言されています

public class ArrayList<E> extends AbstractList<E> implements List<E>,
    Cloneable, Serializable, RandomAccess 

私は今、質問が広がっていると思います、なぜこれを行うのでしょうか。おそらく最適化だと思います。ArrayListArrayはArrayListをListにキャストしているため、残りの通常の機能 なしでList操作を実行するのに十分なだけサポートする必要があります。

于 2012-05-25T17:03:21.073 に答える
1

私は今、質問が広がっていると思います、なぜこれを行うのでしょうか。

(an )Listによって返されます。元の配列のビューです。変更すると配列が変わり、配列を変えると変化します。サイズを変更しようとすると、プリミティブ配列のサイズを変更できないため、例外がスローされます。Arrays.asListArrays.ArrayList

Listこれは、要素をの新しい実装にコピーすることなく、プリミティブ配列を効率的に処理するための単なるアダプターですList

あなたがするとき

new java.util.ArrayList( Arrays.asList( primitiveArray ) );

要素をコピーしているときです。結果はビューではありませんが、元の配列からは独立しています。また、サイズを変更できるようになりました。ソースコードを見ると(との両方を見るjava.util.ArrayList必要がありArrays.ArrayListます。元のプリミティブ配列から、をサポートしている配列に、可能な限り最も効率的な方法でこれらの要素をコピーしていることがわかりますjava.util.ArrayList。したがって、心配する効率。

于 2012-05-25T17:22:23.260 に答える
1

なぜこれを行うのかという疑問が今も残っていると思います

返されるリストは配列のビューであり、コピーは行われず、リストへの変更はソース配列に表示されます。ソース配列によって常にサポートされているため、リストのサイズに影響を与える変更はサポートされておらず、例外がスローされます。

于 2012-05-25T17:08:32.767 に答える
1

あなたが理解すべき最も重要なことは、それArrays.asList完全にパフォーマンスが高いということです。これは、固定オーバーヘッドが非常に小さいO(1)です。これは、データがコピーされていないためです。配列Listと対話するためのインターフェイスを提供するだけです。第 2 に、はデータをコピーしてパフォーマンスを低下させるprivate static class ArrayListため、非常に重要です。public class ArrayList

于 2012-05-25T17:09:35.833 に答える