How does HashSet not allow duplicates?

后端 未结 6 1975
情歌与酒
情歌与酒 2021-02-06 23:17

I was going through the add method of HashSet. It is mentioned that

If this set already contains the element, the call leaves t

6条回答
  •  生来不讨喜
    2021-02-06 23:47

    The answer that you may be looking comes down to the fact that the backing hashmap maps the elements of the set to the value PRESENT which is defined in HashSet.java as follows:

    private static final Object PRESENT = new Object();
    

    In the source code for HashMap.put we have:

      386     public V put(K key, V value) {
      387         if (key == null)
      388             return putForNullKey(value);
      389         int hash = hash(key.hashCode());
      390         int i = indexFor(hash, table.length);
      391         for (Entry e = table[i]; e != null; e = e.next) {
      392             Object k;
      393             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
      394                 V oldValue = e.value;
      395                 e.value = value;
      396                 e.recordAccess(this);
      397                 return oldValue;
      398             }
      399         }
      400 
      401         modCount++;
      402         addEntry(hash, key, value, i);
      403         return null;
      404     }
    

    Because the key in question already exists, we will take the early return on line 397. But you might think a change is being made to the map on line 395, in which it appears that we are changing the value of a map entry. However, the value of value is PRESENT. But because PRESENT is static and final, so there is only one such instance; and so the assignment e.value = value actually doesn't change the map, and therefore the set, at all!

    Update:

    Once a HashSet is initialized.
    - All the items in it are stored as keys in a HashMap
    - All the values that HashMap have ONLY ONE object that is PRESENT which is a static field in HashSet

提交回复
热议问题