JDK源码 0923 HashSet HashTable

进了HashXXX家族,感觉好难啊
HashSet的底层实现竟然是HashMap,年少无知了。不过想想也是复用的典范了。
HashSet 实现了Set接口,实际是由HashMap 实例进行支持,那么同样它也不能保证迭代顺序。

public class HashSet
    extends AbstractSet
    implements Set, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;

    private transient HashMap map;
    /**
     * Constructs a new, empty set; the backing HashMap instance has
     * default initial capacity (16) and load factor (0.75).
     */
    public HashSet() {
        map = new HashMap<>();
    }
 /**
     * Returns an iterator over the elements in this set.  The elements
     * are returned in no particular order.
     *
     * @return an Iterator over the elements in this set
     * @see ConcurrentModificationException
     */
    public Iterator iterator() {
        return map.keySet().iterator();
    }

    /**
     * Returns the number of elements in this set (its cardinality).
     *
     * @return the number of elements in this set (its cardinality)
     */
    public int size() {
        return map.size();
    }

    /**
     * Returns true if this set contains no elements.
     *
     * @return true if this set contains no elements
     */
    public boolean isEmpty() {
        return map.isEmpty();
    }
}

可以看到Set接口中的方法实际都是调用HashMap中已经存在的方法。包含Set的遍历,是取的HashMap中的KeySet()进行遍历。

HashTable 作为与HashMap 一同提起的类,只是这个类是同步进行实现的,且效率慢于HashMap 与 ConcurrentHashMap。遍览全文,发现该类在多处方法调用时候,进行synchronized关键字处理。其实现应与JDK1.7的hashMap基本相同。

public class Hashtable
    extends Dictionary
    implements Map, Cloneable, java.io.Serializable {
 /**
     * The hash table data.
     */
    private transient Entry[] table;

    /**
     * The total number of entries in the hash table.
     */
    private transient int count;

    /**
     * The table is rehashed when its size exceeds this threshold.  (The
     * value of this field is (int)(capacity * loadFactor).)
     *
     * @serial
     */
    private int threshold;

    /**
     * The load factor for the hashtable.
     *
     * @serial
     */
    private float loadFactor;

    /**
     * The number of times this Hashtable has been structurally modified
     * Structural modifications are those that change the number of entries in
     * the Hashtable or otherwise modify its internal structure (e.g.,
     * rehash).  This field is used to make iterators on Collection-views of
     * the Hashtable fail-fast.  (See ConcurrentModificationException).
     */
    private transient int modCount = 0;

    /**
     * Returns the number of keys in this hashtable.
     *
     * @return  the number of keys in this hashtable.
     */
    public synchronized int size() {
        return count;
    }

    /**
     * Tests if this hashtable maps no keys to values.
     *
     * @return  true if this hashtable maps no keys to values;
     *          false otherwise.
     */
    public synchronized boolean isEmpty() {
        return count == 0;
    }
 public synchronized V get(Object key) {
        Entry tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return (V)e.value;
            }
        }
        return null;
    }
  /**
     * Maps the specified key to the specified
     * value in this hashtable. Neither the key nor the
     * value can be null. 

* * The value can be retrieved by calling the get method * with a key that is equal to the original key. * * @param key the hashtable key * @param value the value * @return the previous value of the specified key in this hashtable, * or null if it did not have one * @exception NullPointerException if the key or value is * null * @see Object#equals(Object) * @see #get(Object) */ public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; @SuppressWarnings("unchecked") Entry entry = (Entry)tab[index]; for(; entry != null ; entry = entry.next) { if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } addEntry(hash, key, value, index); return null; } private void addEntry(int hash, K key, V value, int index) { modCount++; Entry tab[] = table; if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash(); tab = table; hash = key.hashCode(); index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. @SuppressWarnings("unchecked") Entry e = (Entry) tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; } }

值得一提的是,实现了Dictionary 抽象类,这是第一次看到这个接口
解释中表明了这个类为抽象父类,作为键值一对一映射,且此类已过时,新的实现应实现Map接口。

你可能感兴趣的:(JDK源码 0923 HashSet HashTable)