1

次のコード スニペットに基づく:

  Hashtable balance = new Hashtable();
  Enumeration names;
  String str;
  double bal;

  balance.put("Zara", new Double(3434.34)); //first entry for Zara
  balance.put("Mahnaz", new Double(123.22));
  balance.put("Zara", new Double(1378.00)); //second entry for Zara
  balance.put("Daisy", new Double(99.22));
  balance.put("Qadir", new Double(-19.08));

  System.out.println(balance.entrySet());

.

Output : [Qadir=-19.08, Mahnaz=123.22, Daisy=99.22, Zara=1378.0]
  1. ここで連鎖が起こっていないのはなぜですか?Zara をキーとして再入力すると、古い値が上書きされます。Zara".hashcode()インデックスのリンク リストの最後に追加されることを期待していました。
  2. Java は衝突処理にのみ個別のチェーンを使用しますか?
  3. チェーンを使用できない場合(上記で試したように)、チェーンを使用するための一般的な方法を提案してください。
4

2 に答える 2

4

Java は衝突処理にのみ個別のチェーンを使用しますか?

はい。a のキーごとに 1 つのエントリしか持つことができませんHashtable(またはHashMap、おそらくジェネリックと共に使用する必要があるものです)。これは、キー/複数値マップではなく、キー/値マップです。ハッシュ テーブルのコンテキストでは、「衝突」という用語は通常、2 つの等しくないキーが同じハッシュ コードを持つ状況に使用されます。それらは依然として異なるキーとして扱われる必要があるため、実装はそれに対処する必要があります。それはあなたがいる状況ではありません。

Guavaのようなマルチマップが必要なようです。次に、特定のキーに関連付けられたすべての値を multimap に問い合わせることができます。

編集: 独自の種類のマルチマップを構築する場合は、次のようになります。

// Warning: completely untested
public final class Multimap<K, V> {
    private final Map<K, List<V>> map = new HashMap<>();

    public void add(K key, V value) {
        List<V> list = map.get(key);
        if (list == null) {
            list = new ArrayList();
            map.put(key, list);
        }
        list.add(value);
    }

    public Iterable<V> getValues(K key) {
        List<V> list = map.get(key);
        return list == null ? Collections.<V>emptyList()
                            : Collections.unmodifiableList(list);
    }
}
于 2014-06-22T08:15:36.980 に答える
3

Map のドキュメントからの引用(これは Hashtable の実装です):

キーを値にマップするオブジェクト。マップに重複キーを含めることはできません。各キーは、最大で 1 つの値にマップできます。

(私のものを強調)

put()のドキュメントにも次のように書かれています。

マップに以前にキーのマッピングが含まれていた場合、古い値は指定された値に置き換えられます

そのため、キーに複数の値を関連付けたい場合は、 のMap<String, List<Double>>代わりに を使用しMap<String, Double>ます。Guava にはMultimapもありますMap<String, List<Double>>

于 2014-06-22T08:18:07.383 に答える