hashtable初探

1、特点:
(1)、线程安全 使用的是synchronized关键字,给hashTable对象加互斥锁;
(2)、 以键值对<k,v>的形式储存
(3)、键和值都不能为null;
(4)、插入无序
2、数据结构:数组+链表
3、底层源码分析:
(1)继承关系:
继承 Dictionary<K,V> , 实现了 Map<K,V>, Cloneable, java.io.Serializable
(2)构造函数:(四个)
注意点1、在建立hashTable对象时底层数组直接被初始化,
注意点2、如果传入的容量大小为0,则初始化时会自动调整为1 ;
(3)默认值 :
默认初始容量 11 , 默认初始负载因子:0.75
(4)增长方式:
扩容临界: 当前size >= 扩容阈值(当前容量 * 负载因子)
rehash方法, 2倍+1 )
(5)基本属性:

Entry[] table;   //数组
int count;//元素个数
float loadFactor; //加载因子
int threshold;  // 阈值
class Entry{}   //内部类

(6)增添查改
A、添加元素**************************************
首先判断value == null?是则抛异常,否则下一步
利用key的hashCode重新hash计算出当前对象的元素在数组中的下标
存储时,如果出现hash值相同的key,此时有两种情况(用equals比较)。
(1)如果key相同,则覆盖原始值;
(2)如果key不同(出现冲突),则将当前的key-value放入链表头部;
容量检查,如果超过阈值,就进行扩容,并重新计算该下标;
如果数组下标处为null,直接新街Entry放入此处;

  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;
	for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
	    if ((e.hash == hash) && e.key.equals(key)) {
		V old = e.value;
		e.value = value;
		return old;
	    }
	}
	modCount++;
	if (count >= threshold) {
	    // 达到临界数目时扩容
	    rehash();  
            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
	}
 //如果数组当前索引位置为null,创建新的Entry,放到当前位置。
	Entry<K,V> e = tab[index];
	tab[index] = new Entry<K,V>(hash, key, value, e);
	count++;
	return null;
    }

B、获取元素 *************************************

获取key的hash值,然后计算对应的索引位置;
遍历当前索引位置下的链表,如果入参key == 链表中某个元素的Key,返回该元素的value;
否则返回null;

   public synchronized V get(Object key) {
	Entry tab[] = table;
	int hash = key.hashCode();
	int index = (hash & 0x7FFFFFFF) % tab.length;
	for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
	    if ((e.hash == hash) && e.key.equals(key)) {
		return e.value;
	    }
	}
	return null;
    }

C、删除元素 *************************************
获取入参key的hash值,计算下标;
在数组指定下标处开始遍历(key==nulltable[0]处遍历查找);
遍历判断 入参 key equals (entry.key)? 是则返回此元素,然后返回其value。

public synchronized V remove(Object key) {
	Entry tab[] = table;
	int hash = key.hashCode();
	int index = (hash & 0x7FFFFFFF) % tab.length;
	for (Entry<K,V> e = tab[index], 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;
    }

4、方法探究

5、HashTable和HashMap的异同

不同点:
(1)主要:HashTable 的线程安全,效率低;
HashMap 的线程不安全,效率高;
(2) 继承关系:HashTable继承dictionary
HashMap继承AbstractMap
(3) null值:HashTable 键和值都不能为null;
HashMap键可以有一个null,值可以有多个null
(4)初始化容量:hashTable的初始化容量为11;
HashMap的初始化容量为16;
(5)扩容倍数:
HashMap:2倍扩容
HashTable:2倍+1
(6)获得hash值计算方式不同;
相同点:
底层数据结构相同;
key不能重复
无序;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值