私はもともとArrayList
を記述し、その中に一意の値(ユーザー名、つまりStrings
)を保存していました。その後、ArrayList
を使用して、ユーザーが存在するかどうかを検索する必要がありました。これが検索用のO(n)
です。
私の技術リーダーは、それをHashMap
に変更し、ユーザー名を配列のキーとして、値を空のStrings
として保存することを望んでいました。
したがって、Java-
_hashmap.put("johndoe","");
_
後で実行すると、このユーザーが存在するかどうかを確認できます-
_hashmap.containsKey("johndoe");
_
これはO(1)
ですよね?
私のリードは、これはこれを行うためのより効率的な方法であり、私には理にかなっていると言いましたが、ハッシュマップの値としてnull/emptyを入れ、その中に要素をキーとして格納するのは少し外れたようです。
私の質問は、これは良いアプローチですか?一般に、効率は_ArrayList#contains
_または配列検索よりも優れています。できます。私の心配は、検索後に他の誰かがこれを行うのを見たことがないということです。どこかで明らかな問題を見逃しているかもしれませんが、それを見ることができません。
一意の値のセットがあるため、Set
が適切なデータ構造です。 HashSet
インターフェースの実装であるSet
内に値を入れることができます。
私のリードは、これはこれを行うためのより効率的な方法であり、私には理にかなっていると言いましたが、ハッシュマップの値としてnull/emptyを入れ、その中に要素をキーとして格納するのは少し外れたようです。
リードのアドバイスに欠陥があります。 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) right?
はい、HashMap
またはHashSet
での検索はO(1)償却された最悪の場合ですが、List
または配列での検索中ですO(n)最悪の場合。
HashSet
がHashMap
の観点から実装されていることを指摘するコメントもあります。 そのレベルの抽象化で。手元のタスクの抽象化レベルでは、一意のユーザー名のコレクションを保存するために、セットを使用するのは自然な選択であり、マップよりも自然です。
これは基本的にHashSet
がどのように実装されるかですので、良いアプローチだと言えると思います。空の値を持つHashSet
の代わりにHashMap
を使用することもできます。
例えば :
HashSet
のadd
の実装は
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
ここで、map
はバッキングHashMap
であり、PRESENT
はダミー値です。
私の心配は、検索後に他の誰かがこれを行うのを見たことがないということです。どこかで明らかな問題を見逃しているかもしれませんが、それを見ることができません。
前述したように、JDKの開発者はこの同じアプローチを使用しています。