2016-08-01 2 views
63

私はもともとArrayListと書かれており、固有の値(ユーザー名、すなわちStrings)がそこに格納されていました。私は後でユーザーがそれに存在するかどうかを検索するためにArrayListを使用する必要がありました。それは検索のためのO(n)です。HashMapのキーとしてデータを空/ヌル値で保存することをお勧めしますか?

技術担当者がHashMapに変更し、ユーザー名をキーとしてアレイに保存し、値を空のStringsにしてほしいと思っていました。 Javaでそう

、 -

hashmap.put("johndoe",""); 

このユーザーが実行することにより、後に存在するかどうか、私は見ることができます -

hashmap.containsKey("johndoe"); 

これはO(1)右ですか?

私の鉛はこれを行うためのより効率的な方法だと私には意味があると言ったが、ハッシュマップに値としてnull/emptyを入れ、その要素をキーとして格納するのはちょっと見えなかった。

私の質問は、これは良いアプローチですか?効率はArrayList#containsまたは一般的な配列検索に勝る。できます。 私の心配は、私は検索後に誰かがこれをやっているのを見たことがありません。私は明らかな問題をどこかで見逃しているかもしれませんが、私はそれを見ることはできません。

+2

plus1 Javaのデータ構造を知らないときは有効な質問です。 – Daniel

+4

'HashSet'は' HashMap.keySet() 'の実装です。マップをセットにしたい場合は、 'set = Collections.newSetFromMap(map)'を使うことができます。 –

+0

この質問は間違っていません。このフォーラムは間違った場所です。 "スタックオーバーフローは、プロと熱心なプログラマーのための質疑応答サイトです"。 – rdllopes

答えて

100

一意の値が設定されているため、Setが適切なデータ構造です。 Setインターフェイスの実装であるHashSetに値を入れることができます。

私のリードは、これはこれを行うには、より効率的な方法であり、それは私には意味をなされたが、それは単にキーとして、その中にハッシュマップや店舗の要素の値として空/ nullを入れて少しオフに見えました。

鉛のアドバイスに欠陥があります。 Mapは、このための適切な抽象化ではありません、Setです。 Mapは、キーと値のペアに適しています。しかし、あなたは値を持っておらず、鍵しか持っていません。

使用例:何が値の型でなければなりませんので

Set<String> users = new HashSet<>(Arrays.asList("Alice", "Bob")); 

System.out.println(users.contains("Alice")); 
// -> prints true 

System.out.println(users.contains("Jack")); 
// -> prints false 

Mapを使用するには、厄介なことでしょうか?あなたのユースケースでは、キーと値のペアではなく、キーだけを持っているので、その質問は意味がありません。 Setでは、あなたはそれを尋ねる必要はなく、使用法は完全に自然です。

これはO(1)ですか? HashMap又はHashSetで検索

はい

は、(1) Listで検索またはアレイはO(n)の最悪の場合であるが、最悪の場合の償却Oです。


いくつかのコメントがHashSetHashMapの面で実装されていることを指摘しています。 そのような抽象レベルのは、です。 手近な作業のレベルで、一意のユーザー名のコレクションを格納する を使用すると、セットを使用する は、マップより自然な選択です。

+2

私がこの答えに同意する間に、「マップ」を望んでいる理由があった場合は、テクニカルリーダーと明確にする必要があります。おそらく、あなたはこのマップを使用してユーザーIDに関連する他の情報を保管することを前提としていますか?メモリ内にユーザ関連のデータを持っている他の理由がある場合は、別の場所に別のコレクションを作成してコードを複製するのではなく、そこに格納することをお勧めします。 – gmiley

+13

HashSetは、空のオブジェクト(すべての値に対して単一のインスタンス)を値として持つHas​​hMapとして実装されています。 –

+0

@JörgWMittag公正なポイント、更新、ありがとう – janos

35

これは基本的にHashSetがどのように実装されているかを示していますので、良いアプローチだと言えます。空の値を持つHashMapの代わりにHashSetを使用することもできます。例えば

add

HashSetの実装はmapバッキングHashMapあり、PRESENTダミー値で

public boolean add(E e) { 
    return map.put(e, PRESENT)==null; 
} 

あります。

私の心配は、他の誰かが検索後にこれを行うのを見たことがないということです。私は明らかな問題をどこかで見逃しているかもしれませんが、私はそれを見ることはできません。

前述したように、JDKの開発者は同じアプローチを使用しています。

+0

ありがとう、ちょっとだけ、HashMap.put( "aaa" 、 "")の代わりにHashSet? また、このアプローチは良いので、配列の冗長性を作っていませんか? – dozer

+21

@dozer HashSetはすでにJDKの一部である既存のクラスですから、なぜ車輪を改造するのですか?配列の冗長性はありません。要素の数が固定され、配列(配列リストだけでなく)が重複を許している場合、配列はより効率的です。 – Eran

+0

@dozerようこそ – Eran

関連する問題