HashMap

  HashMap是基于哈希表的Map接口的实现。HashMap中允许使用NULL键合NULL值。因为在扩容时会发生重构,在重构之后,索引会发生变化,说以不能保证映射的顺序,特别是它不能保证映射顺序的恒久不变。

  HashMap有两个影响性能的因子:初始容量和加载因子。初始容量是哈希表中位置的初始数量。加载因子是表在当前容量下,对于表可以装多满的一种衡量尺度,当表格中的数据量超出了当前容量与加载因子时,哈希表会调用rehash进行扩容(即重建内部数据结构),从而使哈希表具有大约两倍之前的桶数。因为在扩容中会队所有映射重新调用hashCode()计算索引,所以这个过程十分影响效率。因此,在建立哈希表的时候,就对容量和加载因子进行正确预估,对于提高效率十分重要。


一、HashMap的构造方法

HashMap有4种构造方法:

// 默认构造函数。
HashMap()
// 指定“容量大小”的构造函数
HashMap(int capacity)
// 指定“容量大小”和“加载因子”的构造函数
HashMap(int capacity, float loadFactor)
// 包含“子Map”的构造函数
HashMap(Map<? extends K, ? extends V> map)

其中,默认的容量大小为16,默认的加载因子为0.75。

调用的方法为:HashMap<K, V> 表名称 = new HashMap<K, V>()

public class HashMapDemo {
	public static void main(String[]args) {
		HashMap<String, String> hm = new HashMap<String, String>();
	}
}


二、HashMap的存取元素

1.  put(K key, V value)

put方法是我们用来向HashMap中添加元素的方法,key是指定值将要关联的键,value是指定键将要关联的值。

public V put(K key, V value) {
	// 若“key为null”,调用putForNullKey方法,将value放置在数组第一个位置
	if (key == null)
	return putForNullKey(value);
	// 若“key不为null”,则根据key的keyCode重新计算hash值
	int hash = hash(key.hashCode());
	// 搜索指定hash值在对应table中的索引
	int i = indexFor(hash, table.length);
	// 如果 i 索引处的 Entry 不为 null,通过循环不断遍历 e 元素的下一个元素
	for (Entry<K,V> e = table[i]; e != null; e = e.next) {
		Object k;
		// 若key对应的键值对已经存在,则用新的value取代旧的value,并将旧的value返回!
		if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
		V oldValue = e.value;
		e.value = value;
		e.recordAccess(this);
		return oldValue;
		}
	}
	// 若“该key”对应的键值对不存在,则将“key-value”添加到索引i处
	modCount++;
	addEntry(hash, key, value, i);
	return null;
}

HashMap实际上是一个数组加链表的结构,在加入一个元素之后,程序会调用 hashCode() 计算索引,然后将元素存到在数组的对应位置上,如果这个位置上已经有元素存在,那么在同一个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。


2. public V get(Object key)

public V get(Object key) {
	//如果key为空,则getForNullKey,返回数组第一个位置的值
	if (key == null)
		return getForNullKey();
	//如果key不为空,则根据key的值计算hashcode
	int hash = hash(key.hashCode());
	for (Entry<K,V> e = table[indexFor(hash, table.length)];
		e != null;
		e = e.next) {
		Object k;
		if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
			return e.value;
	}
	return null;
}


读取元素时,使用的是get方法,如果key不为空,程序会先计算出keyhashcode值,找到数组中的对应位置,然后通过key.equals(k)来在对应位置的链表中找到需要的元素。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值