Search code examples
javahashhash-collision

Separate chaining for HashTables in Java


Based on the following code snippet :

  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. Why isn't chaining happening here? When I re-enter with Zara as key the old value is overwritten. I expected it to be added at the end of the Linked List at Zara".hashcode() index.
  2. Does Java use separate chaining only for collision handling?
  3. If I can't use chaining( as I'v tried above) please suggest a common method to do so.

Solution

  • Does Java use separate chaining only for collision handling?

    Yes. You can only have one entry per key in a Hashtable (or HashMap, which is what you should probably be using - along with generics). It's a key/value map, not a key/multiple-values map. In the context of a hash table, the term "collision" is usually used for the situation where two unequal keys have the same hash code. They still need to be treated as different keys, so the implementation has to cope with that. That's not the situation you're in.

    It sounds like you might want a multi-map, such as one of the ones in Guava. You can then ask a multimap for all values associated with a particular key.

    EDIT: If you want to build your own sort of multimap, you'd have something like:

    // 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);
        }
    }