HashTable特性

  • HashTable是线程安全的集合,通过synchronized关键字实现;
  • HashTable的key和value均不允许为null,使用会产生空指针问题;

HashTable源码分析

  • table是一个数组,表示哈希桶;
  • count表示存储的元素个数;
  • loadFactor表示负载因子,默认值是0.75,这是时间和空间权衡后的最优值;
  • threshold表示元素存储的阈值,容量*负载因子可以得到该值;

HashTable初始化

  1. /**
  2. * Constructs a new, empty hashtable with the specified initial
  3. * capacity and the specified load factor.
  4. *
  5. * @param initialCapacity the initial capacity of the hashtable.
  6. * @param loadFactor the load factor of the hashtable.
  7. * @throws IllegalArgumentException if the initial capacity is less
  8. * than zero, or if the load factor is nonpositive.
  9. */
  10. public Hashtable(int initialCapacity, float loadFactor) {
  11. if (initialCapacity < 0)
  12. throw new IllegalArgumentException("Illegal Capacity: "+
  13. initialCapacity);
  14. if (loadFactor <= 0 || Float.isNaN(loadFactor))
  15. throw new IllegalArgumentException("Illegal Load: "+loadFactor);
  16. if (initialCapacity==0)
  17. initialCapacity = 1;
  18. //初始化负载因子、数组和存储元素的阈值
  19. this.loadFactor = loadFactor;
  20. table = new Entry<?,?>[initialCapacity];
  21. threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
  22. }

put操作

  1. /**
  2. * Maps the specified {@code key} to the specified
  3. * {@code value} in this hashtable. Neither the key nor the
  4. * value can be {@code null}. <p>
  5. *
  6. * The value can be retrieved by calling the {@code get} method
  7. * with a key that is equal to the original key.
  8. *
  9. * @param key the hashtable key
  10. * @param value the value
  11. * @return the previous value of the specified key in this hashtable,
  12. * or {@code null} if it did not have one
  13. * @throws NullPointerException if the key or value is
  14. * {@code null}
  15. * @see Object#equals(Object)
  16. * @see #get(Object)
  17. */
  18. public synchronized V put(K key, V value) {
  19. // HashTable的key和value都不允许为null,否则会产生空指针
  20. if (value == null) {
  21. throw new NullPointerException();
  22. }
  23. // Makes sure the key is not already in the hashtable.
  24. Entry<?,?> tab[] = table;
  25. int hash = key.hashCode();
  26. int index = (hash & 0x7FFFFFFF) % tab.length;
  27. @SuppressWarnings("unchecked")
  28. Entry<K,V> entry = (Entry<K,V>)tab[index];
  29. //如果有相同的entry,替换对应的value
  30. for(; entry != null ; entry = entry.next) {
  31. if ((entry.hash == hash) && entry.key.equals(key)) {
  32. V old = entry.value;
  33. entry.value = value;
  34. return old;
  35. }
  36. }
  37. //如果没有对应的entry,新增一个Entry,链表的插入使用头插法
  38. addEntry(hash, key, value, index);
  39. return null;
  40. }

HashTable计算桶位置的公式:

  1. int index = (hash & 0x7FFFFFFF) % tab.length;

在此处做&操作的目的是获取到正整数。