2009-08-19 20 views
19

TreeSetの賛否両論が何であるか疑問に思っています。ありがとう!TreeSetの長所と短所

+0

これらの質問とそれに対応する回答はそこにあるはずです。非常に役立ちます!ありがとうございました! – mtical

答えて

23

Collectionクラスの1つです。それは、あなたのコレクション内の要素にキーで、または順次キーにアクセスすることができます。 ArrayListやHashMapよりもかなりオーバーヘッドがあります。シーケンシャルアクセスを必要としない場合は、キーでルックアップするだけでHashSetを使用してください。 ArrayListを使用し、配列を使用します。要素を整列させたい場合はソートしてください。 TreeSetは、要素を常に順番に保持します。 ArrayListを使用すると、必要なときに並べ替えることができます。 TreeSetsでは、キーはコレクションに格納されているオブジェクトに埋め込まれている必要があります。多くの場合、TreeSet of Stringsがあります。指定したStringがSetに含まれているかどうかを確認するだけです。それは、あなたにTreemapのやり方とは関係のないオブジェクトを見つけることはありません。 TreeMapを使用すると、関連付けられているキーとオブジェクトは別々のものになります。

TreeSetとその兄弟TreeMapは、奇妙なことに木を表現することとは関係がありません。内部的には、ツリー構造を使用してアルファベット順にソートされたセット/マップを提供しますが、親と子の間のリンクを制御することはできません。

内部的にTreeSetは赤黒のツリーを使用します。バランスの取れたツリーを得るためにデータを事前に並べる必要はありません。一方、データがソート(昇順または降順)されている場合、他のタイプのツリーと同様に傷つくことはありません。

あなたが望む順序を定義するためにコンパレータを指定しない場合、TreeSetは自然順序を定義するためにアイテムクラスにComparable実装を必要とします。

+4

です。典型的な使用例:テキストを取得し、このテキストからすべての単語をTreeSet にドロップし、イテレータは、アルファベット順のソート済みワードインデックス(重複なし)を提供します。 –

+0

"キーでルックアップするだけで、シーケンシャルアクセスが不要な場合はHashSetを使用してください。" –

+0

特定のシーケンシャルアクセスが必要でソートが必要ない場合は、入力データの順序を保持するLinkedHashSetを使用できます。また、TreeSetはlognの順序を削除していますが、PriorityQueueの削除順序はO(n) –

3

TreeSet:
長所:赤/黒のツリーアルゴリズムに基づいてソートされ、操作にO(log(N))の複雑さを提供します。
短所:値はのいずれかである必要があります。またはコンパレータをコンストラクタに指定する必要があります。さらに、HashSet実装は〜O(1)の複雑さを提供するため、より良いパフォーマンスを提供します。

+0

ありがとうたくさんの芽! – Rifk

+0

"red/black treeアルゴリズムに基づいて" "プロ"としてmetionに奇妙に思えます。 TreeSetを比較する明白な事が(あなたが言ったように)より良い時間の複雑さを持つHas​​hSetであるとき、プロとしてのO(log(N))の複雑さに言及するのもちょっと変わったようです。 –

+1

@Laurence:1)一意性のチェックを含めると、O(log(N))はそれに対する「プロ」ですので、リストへの挿入はO(N)です。 2)適切なハッシュ関数を使用し、ハッシュテーブルを大きくすることができる場合、HashSetはO(1)だけです。 –

0

このデータ構造は、昇順検索が可能なようにデータを維持するためにバイナリツリーを使用すると思われます。その場合、ツリーをバランスさせて維持しようとすると、削除操作が多少コストがかかることになります。

+1

-1:HashSetは赤黒のツリーを使用します。 [このページ](http://www.eli.sdsu.edu/courses/fall95/cs660/notes/RedBlackTree/RedBlack.html)によると、削除の複雑さはO(log(N)) –

9

短所:TreeSetの落とし穴の1つは、予期しない方法でSetインターフェイスを実装していることです。 TreeSetにオブジェクトaが含まれている場合、a.equals(b)がfalseであっても、a.compareTo(b)が0を返した場合、オブジェクトbはセットの一部とみなされるため、compareToとequalsが一貫性あなたは悪い乗り方のためにいる。

これは、メソッドがSetを返し、実装がTreeSetか、たとえばHashSetかどうかわからないときに特に問題になります。

ここで学ぶべきことは、常にcompareToとequalsが一貫して実装されないようにすることです。 equalsと矛盾する方法でオブジェクトを注文する必要がある場合は、Comparatorを使用します。

+1

を使用する義務は、 "a.compareTo(b)がゼロを返すかどうか"と言ったかったでしょうか? –

+1

うわー。 4歳のポストに関する建設的なフィードバック。ありがとう、私はそれを修正しました。 – Buhb

2

TreeSetはメモリを断片化し、追加のメモリオーバーヘッドを持ちます。ソースを見て、追加のメモリの量とそれが作成する追加オブジェクトの量を計算することができます。もちろん、それは格納されたオブジェクトの性質に依存し、また私はメモリについての妄想であると疑うことができます:)しかし、それはこことそこに費やさない方が良いです - あなたはGCを持っています、あなたはキャッシュミスを持っていて、

多くの場合、TreeSetではなくPriorityQueueを使用できます。そして、典型的なユースケースでは、文字列の配列をソートする方が良いでしょう。

関連する問題