web-dev-qa-db-ja.com

リストとセットのパフォーマンスとメモリ割り当ての比較

List、Setのパフォーマンス、メモリ割り当て、使いやすさの比較を知りたいです。

オブジェクトのリストで一意性を維持する必要がない場合、挿入順序を維持する必要もありません。ArrayListとSortedSet/HashSetを同じように使用できますか? list/setでなく、Collectionsクラスを直接使用するのは良いでしょうか?

追伸また、Javaが提供する特定の関数をリストしたり設定したりする必要もありません。配列の代わりにリスト/セットを使用しているのは、追加のプログラミング作業なしで動的に成長できるからです。

52
Priyank Doshi

順序を気にせず、要素を削除しない場合、実際には、このデータ構造内で要素を見つける必要があるかどうか、およびそれらのルックアップをどれだけ速くするかが重要になります。

HashSetの値で要素を見つけることはO(1)です。 ArrayListでは、O(n)です。

コンテナを使用して一意のオブジェクトの束を格納し、最後に(任意の順序で)繰り返し処理する場合は、ArrayListの方が簡単で経済的であるため、おそらくより良い選択です。

47
NPE

HashSetは、同じ数の要素に対してArrayListの約5.5倍のメモリを消費し(どちらもまだ線形ですが)、反復が大幅に遅くなります(同じ漸近性ではありますが)。簡単なGoogle検索では、HashSetの反復がArrayListに対して2〜3倍遅くなることが示唆されています。

containsの一意性やパフォーマンスを気にしない場合は、ArrayListを使用します。

77
Louis Wasserman

要素を追加するだけで、後でそれらを反復する場合、最善の方法は、置換する配列に最も近いArrayListです。 LinkedListまたはSet実装よりもメモリ効率が高く、挿入、反復、ランダムアクセスが高速です。

3
Marko Topolnik

リストとセットを検索して比較すると、下線のハッシュアルゴリズムによりセットの方が優れています。

リストの場合、最悪の場合、containsは最後まで検索します。 Setの場合、ハッシュとバケットのため、サブセットのみを検索します。

ユースケースの例:ArrayListおよびHashSetに1〜100_000の整数を追加します。 ArrayListおよびHashSetの各整数を検索します。

セットには9ミリ秒かかりますが、リストには16232秒かかります。

private static void compareSetvsList(){
    List<Integer> list = new ArrayList<>() ;
    Set<Integer> set = new HashSet<>() ;

    System.out.println("Setting values in list and set .... ");
    int counter = 100_000  ;

    for(int i =0 ; i< counter ; i++){            
        list.add(i);
        set.add(i);
    }

    System.out.println("Checking time .... ");
    long l1 = System.currentTimeMillis();
    for(int i =0 ; i< counter ; i++) list.contains(i);

    long l2 = System.currentTimeMillis();
    System.out.println(" time taken for list : "+ (l2-l1));

    for(int i =0 ; i< counter ; i++)set.contains(i);

    long l3 = System.currentTimeMillis();
    System.out.println(" time taken for set : "+ (l3-l2));

    //      for 10000   time taken for list : 123        time taken for set : 4
    //      for 100000  time taken for list : 16232          time taken for set : 9
    //      for 1000000 time taken for list : hung       time taken for set : 26

}
1
Manoj

.contains(T)を頻繁に使用する必要がある場合は、HashSetを使用します。

例:

private static final HashSet<String> KEYWORDS = Stream.of(new String[]{"if", "do", "for", "try", "while", "break", "return"}).collect(Collectors.toCollection(HashSet::new));

public boolean isKeyword(String str) {
     return KEYWORDS.contains(str);
}
0
Dave_cz

collectionに一意の要素を含める必要がない場合は、特別なニーズがない限り、単にArrayListを使用します。

collectionに一意の要素のみを含める必要がある場合は、特別なニーズがない限りHashSetを使用します。

SortedSet(およびその実装者TreeSet)については、JavaDocに従って:

要素の全体的な順序付けをさらに提供するセット。要素は、自然な順序を使用して、またはソートセットの作成時に通常提供されるコンパレータによって順序付けられます。

つまり、通常は必要ないsetで要素を常に順序付けする必要がある、非常に特定のユースケースを対象としています。

0