web-dev-qa-db-ja.com

Java HashSetとアレイのパフォーマンス

区別できることが保証されているオブジェクトのコレクションがあります(特に、一意の整数IDでインデックスが付けられています)。また、それらがいくつあるか(そしてその数は変わらない)を正確に知っており、これらの要素を格納/取得するために、ArrayがHashSetよりも顕著なパフォーマンス上の利点があるかどうか疑問に思っていました。

紙の上では、Arrayは一定時間の挿入(サイズを事前に知っているため)と取得を保証しますが、HashSetのコードははるかにきれいに見え、ある程度の柔軟性が追加されるため、パフォーマンス面で何かを失うのではないかと思います。 、少なくとも理論的には。

12
donnyton

データによって異なります。

HashSetO(1) contains()メソッドを提供しますが、順序は保持しません。

ArrayList contains()はO(n)ですが、エントリの順序を制御できます。

Array間に何かを挿入する必要がある場合、データを下に移動して挿入用のスペースを確保する必要があるため、最悪の場合はO(n)になる可能性があります。 Setでは、SortedSet which too has O(n) too but with flexible operations.を直接使用できます

セットの方が柔軟だと思います。

21
JNL

エンタープライズソフトウェアの場合、スケーラブルで保守可能でクリーンなコードの方がはるかに優れています。だから私はHashSetに行きます。

2
auhuman

選択は、それをどうするかによって大きく異なります。

それがあなたの質問で言及されたものである場合:

collectionのオブジェクトがあり、それらは区別できることが保証されています(特に、一意の整数IDでインデックスが付けられています)。私も正確に知っていますそれらがいくつあるか

これがあなたがする必要があることであるならば、あなたはそれらのどちらも必要としません。 Collectionにはsize()メソッドがあり、そのサイズを取得できます。つまり、コレクションにはいくつあるかです。

「オブジェクトのコレクション」の意味が実際にはコレクションではなく、さらに処理するためにオブジェクトを格納するコレクションのタイプを選択する必要がある場合は、コレクションの種類ごとに異なる機能があり、特性。

まず、公正な比較があると思います。再割り当てを処理する必要がないArrayの代わりにArrayListを使用することを検討する必要があります。

次に、ArrayListとHashSetの選択になります。これは非常に簡単です。

リストまたはセットが必要ですか?それらは異なる目的のためのものです。リストはインデックス付きアクセスを提供し、反復はインデックス順になります。セットは主にデータの個別のセットを保持するためのものであり、その性質上、インデックスにアクセスすることはできません。

使用するリストまたはセットを決定した後、それはリスト/セットの実装の選択です。通常、リストの場合はArrayListとLinkedListから選択し、セットの場合はHashSetとTreeSetのいずれかを選択します。

すべての選択は、そのデータのコレクションで何をしたいかによって異なります。それらは、異なるアクションで異なるパフォーマンスを示します。

たとえば、ArrayListのインデックス付きアクセスはO(1)、HashSetのインデックス付きアクセス(意味はありませんが)はO(n)です(念のため、LinkedListのインデックス付きアクセスはO(n)、TreeSetのインデックス付きアクセスはO(nlogn))

新しい要素を追加する場合、ArrayListとHashSetはどちらもO(1)操作です。ArrayListの場合、中央に挿入するのはO(n)ですが、 tはHashSetで意味があります。どちらも再割り当てに悩まされ、両方とも再割り当てにO(n)が必要です(HashSetは通常、各要素のハッシュの計算を伴うため、再割り当てが遅くなります)再び)。

コレクションに特定の要素が存在するかどうかを確認するには、ArrayListはO(n)で、HashSetはO(1)です。

実行できる操作はまだたくさんあるので、何をしたいのかを知らずにパフォーマンスについて議論することはまったく意味がありません。

1
Adrian Shum

IDをカウントにマップするHashMapが必要になるようです。特に、

HashMap<Integer,Integer> counts=new HashMap<Integer,Integer>();
counts.put(uniqueID,counts.get(uniqueID)+1);

このようにして、償却されますO(1)追加、包含、および取得。基本的に、各オブジェクトに関連付けられた一意のIDを持つ配列ISHashMap。By HashMapを使用すると、配列のサイズを管理する必要がなく、キーを配列インデックスに自分でマップする必要がなく、アクセス時間が一定であるという追加のボーナスが得られます。

0
anguyen

理論的に、そしてSCJP6研究ガイドが言うように:D

配列はコレクションよりも高速であり、前述のように、ほとんどのコレクションは主に配列に依存しています(マップはコレクションとは見なされませんが、コレクションフレームワークに含まれています)

要素のサイズが変わらないことが保証されている場合は、ルートオブジェクトを直接使用できるのに(配列)、オブジェクト上に構築されたオブジェクト(配列上に構築されたコレクション)でスタックするのはなぜですか?

0