a) 其拥有一个内部类的数组,而内部类为一个链表,即为一个个桶。通过一个对对象的hash码的算法作为key。
b) 很重要的是,如果一个类想要存放进HashTable的key,必须要严格的重写equeals()方法和hashCode方法。
c) 在通过其他途径获得迭代器后,也是快速失败的,即不能通过非迭代器的方法改变此类的结构
3. 简单源码了解
1. put(Kkey,T value):
1. publicsynchronized Vput(Kkey, Vvalue) {
2. // Make sure the value is not null
3. if (value ==null){
4. thrownew NullPointerException();
5. }
6.
7. // Makes sure the key is not already in the hashtable.
8. Entry tab[] = table;
9. inthash =key.hashCode();
10. intindex = (hash& 0x7FFFFFFF) %tab.length;
11. for (Entry<K,V>e =tab[index];e !=null ;e =e.next) {
12. if ((e.hash ==hash) &&e.key.equals(key)) {
13. V old = e.value;
14. e.value =value;
15. returnold;
16. }
17. }
18.
19. modCount++;
20. if (count >=threshold){
21. // Rehash the table if the threshold is exceeded
22. rehash();
23.
24. tab =table;
25. index = (hash & 0x7FFFFFFF) %tab.length;
26. }
27.
28. // Creates the new entry.
29. Entry<K,V> e = tab[index];
30. tab[index] =newEntry<>(hash,key,value,e);
31. count++;
32. returnnull;
33. }
可以看出,得到对象的Hash码之后,便进行(hash&0x7FFFFFFF) %tab.length运算,得到桶的位置,遍历桶,插入对象
2. rehash()
1. protectedvoidrehash() {
2. intoldCapacity =table.length;
3. Entry[] oldMap = table;
4.
5. // overflow-conscious code
6. intnewCapacity = (oldCapacity<< 1) + 1;
7. if (newCapacity -MAX_ARRAY_SIZE > 0) {
8. if (oldCapacity ==MAX_ARRAY_SIZE)
9. // Keep running with MAX_ARRAY_SIZE buckets
10. return;
11. newCapacity =MAX_ARRAY_SIZE;
12. }
13. Entry[] newMap = new Entry[newCapacity];
14.
15. modCount++;
16. threshold = (int)(newCapacity *loadFactor);
17. table =newMap;
18.
19. for (inti =oldCapacity;i-- > 0 ;) {
20. for (Entry<K,V>old =oldMap[i] ;old !=null ; ) {
21. Entry<K,V>e =old;
22. old =old.next;
23.
24. intindex = (e.hash & 0x7FFFFFFF) %newCapacity;
25. e.next =newMap[index];
26. newMap[index] =e;
27. }
28. }
29. }
可以看出,当接近HashTable的容量时,会新申请一个Entity数组来扩增,扩增容量大致为原来的两倍