public static void main(String[] args) {
Hashtable<String,Integer> hashtable=new Hashtable<String, Integer>();
/**hashtable底层数据结构:数组+链表
* 不能存储Null值
* 不能保证插入有序
* 线程安全
* 增加元素,数组扩容方式为2倍+1的方式,初始容量为11
* 继承Dictionary<K,V>类,提供了特有的遍历方式(枚举遍历Enumeration:)其中有
* boolean hasMoreElements()和E nextElement()方法,在hashtable中调用使用elements()方法调用
* 同时实现implements Map<K,V>, Cloneable, java.io.Serializable接口
*/
hashtable.put("ls",18);//插入元素
hashtable.put("zs",19);
//put源码分析:
/**初始容量和加载因子
* public Hashtable() {
* this(11, 0.75f);
* }
* public synchronized V put(K key, V value) {
* if (value == null) {// 1.说明value值不能为null
* throw new NullPointerException();
* }
* Entry<?,?> tab[] = table;
* int hash = key.hashCode();//计算哈希值,此处说明value值不能为null,否则会出现空指针异常
* int index = (hash & 0x7FFFFFFF) % tab.length;//计算位置
* Entry<K , V> entry = (Entry<K,V>)tab[index];
* for(; entry != null ; entry = entry.next) {//遍历查找是否插入的新元素和旧元素hash值和key值相等,
* 如果相等用新的value替换旧的value,并返回旧的value,否则跳出for循环。直接插入元素
*
* if ((entry.hash == hash) && entry.key.equals(key)) {
* V old = entry.value;
* entry.value = value;
* return old;
* }
* }
*
* addEntry(hash, key, value, index);//存在扩容机制
* return null;
* }
* //添加元素addEntry
* private void addEntry(int hash, K key, V value, int index) {
* modCount++;
* Entry<?,?> tab[] = table;
* if (count >= threshold) {
* 如果大于阈值需要重哈希,
* rehash();
*
* tab = table;
* hash = key.hashCode();
* index = (hash & 0x7FFFFFFF) % tab.length;//与hashmap的计算哈希位置不同
* }
* Entry<K , V> e = (Entry<K,V>) tab[index];
* tab[index] = new Entry<>(hash, key, value, e);
* count++;
* }
* 重哈希
* protected void rehash() {
* int oldCapacity = table.length;
* Entry<?,?>[] oldMap = table;
* int newCapacity = (oldCapacity << 1) + 1;//2倍+1的方式扩容数组
* if (newCapacity - MAX_ARRAY_SIZE > 0) {
* if (oldCapacity == MAX_ARRAY_SIZE)
* return;
* newCapacity = MAX_ARRAY_SIZE;
* }
* Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];
*
* modCount++;
* //重新计算阈值:新的容量*加载因子和最大值+1中最小的值,阈值的作用显然实在添加元素是判断是否扩容数组发挥作用
* threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
* table = newMap;
* //将旧的元素通过for循环放入新的数组
* for (int i = oldCapacity ; i-- > 0 ;) {
* for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) {
* Entry<K,V> e = old;
* old = old.next;
*
* int index = (e.hash & 0x7FFFFFFF) % newCapacity;
* e.next = (Entry<K,V>)newMap[index];
* newMap[index] = e;
* }
* }
* }
*
*
*/
hashtable.remove("ls");
/**
* 删除元素:
* 1.计算哈希值
* 2.通过哈希值找位置
* 3.通过位置找节点,遍历整个链表,如果存在,根据链表的删除元素的方法删除即可,
* 最后需要将value值赋值为null,避免内存泄漏
*
*
* public synchronized V remove(Object key) {
* Entry<?,?> tab[] = table;
* int hash = key.hashCode();
* int index = (hash & 0x7FFFFFFF) % tab.length;
* Entry<K , V> e = (Entry<K,V>)tab[index];
* for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) {
* if ((e.hash == hash) && e.key.equals(key)) {
* modCount++;
* if (prev != null) {
* prev.next = e.next;
* } else {
* tab[index] = e.next;
* }
* count--;
* V oldValue = e.value;
* e.value = null;
* return oldValue;
* }
* }
* return null;
* }
*
*/
Integer ls = hashtable.get("ls");
/**
* 通过键获取元素,也是:
* 1.计算哈希值
* 2.通过哈希函数计算位置
* 3.遍历查找,返回value
* 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;
* }
*
*/
hashtable.contains("ls");
/**
*
* public synchronized boolean contains(Object value) {
* if (value == null) {
* throw new NullPointerException();//value值不能为null
* }
* 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;
* }
*/
/**
*
* 遍历方式有四种,如下
*/
//使用枚举的方法遍历
Enumeration<Integer> elements = hashtable.elements();
while (elements.hasMoreElements()){
Integer integer = elements.nextElement();
System.out.println(integer);
}
//节点的方式遍历
Set<Map.Entry<String, Integer>> entries = hashtable.entrySet();
Iterator<Map.Entry<String, Integer>> iterator = entries.iterator();
while (iterator.hasNext()){
Map.Entry<String, Integer> next = iterator.next();
System.out.println(next.getValue());
}
//key遍历
Set<String> strings = hashtable.keySet();
Iterator<String> iterator1 = strings.iterator();
while (iterator1.hasNext()){
String next = iterator1.next();
System.out.println(next);
}
//value值遍历
Collection<Integer> values = hashtable.values();
Iterator<Integer> iterator2 = values.iterator();
while (iterator2.hasNext()){
Integer next = iterator2.next();
System.out.println(next);
}
}