零、搞完HashMap之后,hashSet就很简单了。这里顺便就把HashSet带过了。
一、签名
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable |
二、成员变量
private transient HashMap<E,Object> map; //hashSet底层用HashMap实现。 |
private static final Object PRESENT = new Object(); |
三、构造方法
public HashSet() { map = new HashMap<>(); } |
public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } |
public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } |
public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } |
HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); } |
四、成员方法:
public boolean isEmpty() { return map.isEmpty(); } |
public boolean contains(Object o) { return map.containsKey(o); } |
public boolean add(E e) { return map.put(e, PRESENT)==null; } |
public boolean remove(Object o) { return map.remove(o)==PRESENT; } |
五、遍历方式:
一、总结:
看了HashMap之后,在看这个真的一点要敲黑板的地方都没有!~
jdk源码分析六 java.util.HashTable<K,V> since 1.0
一、签名
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable { |
Dictionary接口:所有包含key和value的抽象父类。
二、成员变量
private transient Entry<?,?>[] table; // |
private transient int count; // table的大小 |
private int threshold; // 阈值 |
private float loadFactor; // 装载因子 |
private transient int modCount = 0; //用于fast-fial策略,记录结构修改次数。 |
private static class Entry<K,V> implements Map.Entry<K,V> { //单向链表。 final int hash; final K key; V value; Entry<K,V> next;
protected Entry(int hash, K key, V value, Entry<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; }
@SuppressWarnings("unchecked") protected Object clone() { return new Entry<>(hash, key, value, (next==null ? null : (Entry<K,V>) next.clone())); }
// Map.Entry Ops
public K getKey() { return key; }
public V getValue() { return value; }
public V setValue(V value) { if (value == null) throw new NullPointerException();
V oldValue = this.value; this.value = value; return oldValue; }
public boolean equals(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry<?,?> e = (Map.Entry<?,?>)o;
return (key==null ? e.getKey()==null : key.equals(e.getKey())) && (value==null ? e.getValue()==null : value.equals(e.getValue())); }
public int hashCode() { return hash ^ Objects.hashCode(value); }
public String toString() { return key.toString()+"="+value.toString(); } } |
三、构造方法
public Hashtable(int initialCapacity, float loadFactor) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal Load: "+loadFactor);
if (initialCapacity==0) initialCapacity = 1; this.loadFactor = loadFactor; table = new Entry<?,?>[initialCapacity]; threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1); } |
public Hashtable(int initialCapacity) { this(initialCapacity, 0.75f); } |
public Hashtable() { this(11, 0.75f); //这里直接写死了,默认大小就是11. 装载 } |
public Hashtable(Map<? extends K, ? extends V> t) { this(Math.max(2*t.size(), 11), 0.75f); putAll(t); } |
四、成员方法
public synchronized int size() { return count; } |
public synchronized boolean isEmpty() { return count == 0; } |
public synchronized Enumeration<K> keys() { return this.<K>getEnumeration(KEYS); } |
public synchronized Enumeration<V> elements() { return this.<V>getEnumeration(VALUES); } |
public synchronized boolean contains(Object value) { if (value == null) { throw new NullPointerException(); }
Entry<?,?> tab[] = table; for (int i = tab.length ; i-- > 0 ;) { for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) { if (e.value.equals(value)) { return true; } } } return false; } |
public synchronized boolean containsKey(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 true; } } return false; } |
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; } |
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<K,V> entry = (Entry<K,V>)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<K,V> e = (Entry<K,V>) tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; } |
五、总结
1. HashTable是基于Dictionary类的、
2. Hashtable中的方法是同步的,保证了hashTable中对象的线程安全。
3. 内部实现是数组加链表。默认大小是11,增加的方式是old*2+1;
4. Hashtable中,key和value都不能为空。