6

今日、次のように静的メソッドを利用して新しい ArrayList オブジェクトを作成できることを学びました。

List<String> listDummy = Arrays.asList("Coding", "is", "fun"); 
ArrayList<String> stringList = new ArrayList<>(listDummy);

またはさらに簡潔に:

ArrayList<String> stringList = new ArrayList<>(Arrays.asList("Coding", "is", "fun"));

私の質問は次のとおりです。「従来の」方法と比較して、このパフォーマンスはどれくらい高価ですか? (下)

ArrayList<String> stringList = new ArrayList<>();
stringList.add("Coding");
stringList.add("is");
stringList.add("fun");

ArrayList を作成する上位の方法には、余分な List オブジェクトの作成が含まれていることは理解していますが、パフォーマンスをいくらか犠牲にしても構わないが、どこかで線を引かなければならない程度に、短くてコンパクトな構文を好みます。

PS。「new ArrayList<>()」でタイプ情報(<>)を空のままにしておくことは、エラーではなくJava SE 7の機能です。

ご回答ありがとうございます。

4

7 に答える 7

5

パフォーマンスの差は、システムとコードのウォームアップの程度によって 30 ~ 300 ns になる可能性があります。性能差は小さいと思います。

疑わしい場合は、私はいつも言います。コードをできる限りシンプルかつ明確に記述すれば、多くの場合、問題なく動作します。

于 2013-06-11T10:16:36.413 に答える
1

作成後にリストから要素を追加/削除しない場合、最善の方法は ArrayList をまったく作成しないことです。これは非常に効率的です。

List<String> listDummy = Arrays.asList("Coding", "is", "fun"); 

それ以外の場合new ArrayList<>(listDummy)は、要素を 1 つずつ手動で追加するよりも効率的です。ArrayList(Collection) src を参照してください。

public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    size = elementData.length;
    // c.toArray might (incorrectly) not return Object[] (see 6260652)
    if (elementData.getClass() != Object[].class)
        elementData = Arrays.copyOf(elementData, size, Object[].class);
}

最適化されています:

1) 正確なサイズの配列を作成する
2) 要素のネイティブ コピーを使用する

于 2013-06-11T10:19:33.610 に答える
1

Arrays.asList から取得したリストは既に ArrayList であるため、再度 ArrayList でラップする必要はありません。

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

警告: リストは読み取り専用なので、書き込む必要がある場合は、実際に new ArrayList(..) を使用してラップする必要があります。

それでも、ArrayList の内部配列は正しいサイズで初期化されるため、「add」を繰り返し呼び出してリストを作成するよりも、Arrays.asList を使用する方がよいと思います。だから最善の方法は

List<String> myList= Arrays.asList("Coding", "is", "fun");
// or if you need to write the list
List<String> myList = new ArrayList(Arrays.asList("Coding", "is", "fun"));

また、これは最も読みやすい IMHO であり、追加のパフォーマンスが本当に必要でない限り、私にとって読みやすさは常に非常に小さなパフォーマンスの向上よりも優先されます。本当にパフォーマンス チューニングが必要な場合は、プロファイラーを使用してください。ボトルネックは通常、予期しないところにあります。プロファイラーは、プログラムのどの部分が遅いかについて正確な情報を提供し、必要に応じてそれらを最適化できます。

于 2013-06-11T10:19:53.520 に答える
0

パフォーマンスの違いは、ソース配列のサイズによって異なります。

項目を 1 つずつ追加すると、宛先配列内で複数の再割り当てが発生します。

コレクション全体を一度に追加する場合は、サイズが事前にわかっているため、1 つの割り当てのみを行う必要があります。

于 2013-06-11T10:21:25.517 に答える
0

私は時々便利な関数を使用します:

public static <T> ArrayList<T> asArrayList(T... args) {
    ArrayList<T> list = new ArrayList<T>(args.length);
    Collections.addAll(list, args);
    return list;
}

これはArrays.asListルートよりも少し速いです。(ハードコードされたリストでは、それが実際に問題になるわけではありません。)

于 2013-06-11T11:23:14.550 に答える