Java集合源码学习(20)_Map接口的实现HashMap

1:继承自AbstractMap类;允许null值,null的key和null的value均可;不保证元素有序;

2:get和put方法时间复杂度基本为o(1);通过hash将元素映射到对应的bucket;

3:initCapacity和loadFactor参数:initCapacity是hash表中bucket的初始数量;

【TODO】还没有理解这两个参数的意义!和源码有出入?为什么size>(capacity*factor)时候调整entry[]的大小?这样岂不是entry[]数组大小永远大于实际的元素数量?

4:实现了一个Entry

static class Entry<K, V> implements Map.Entry<K, V> {
	final K key;
	V value;
	Entry<K, V> next;
	final int hash;
}

5:确定一个元素要存到那个entry中:

int hash = hash(key.hashCode());//hash
int i = indexFor(hash, table.length);//根据hash值获得entry[]的下标记
static int hash(int h) {
	// This function ensures that hashCodes that differ only by
	// constant multiples at each bit position have a bounded
	// number of collisions (approximately 8 at default load factor).
	h ^= (h >>> 20) ^ (h >>> 12);
	return h ^ (h >>> 7) ^ (h >>> 4);
}
static int indexFor(int h, int length) {
	return h & (length - 1);
}
6:插入元素时,有可能需要调整entry[]大小,重构entry[]

void addEntry(int hash, K key, V value, int bucketIndex) {
	Entry<K, V> e = table[bucketIndex];
	table[bucketIndex] = new Entry<K, V>(hash, key, value, e);
	<span style="color:#ff0000;">if (size++ >= threshold)//TODO 这个地方不太理解</span>
		resize(2 * table.length);
}
重构方法:

void resize(int newCapacity) {
	Entry[] oldTable = table;
	int oldCapacity = oldTable.length;
	if (oldCapacity == MAXIMUM_CAPACITY) {
		threshold = Integer.MAX_VALUE;
		return;
	}
	Entry[] newTable = new Entry[newCapacity];
	transfer(newTable);
	table = newTable;
	threshold = (int) (newCapacity * loadFactor);
}
/**
 * Transfers all entries from current table to newTable.
 */
void transfer(Entry[] newTable) {
	Entry[] src = table;
	int newCapacity = newTable.length;
	for (int j = 0; j < src.length; j++) {
		Entry<K, V> e = src[j];
		if (e != null) {
			src[j] = null;
			do {
				Entry<K, V> next = e.next;
				int i = indexFor(e.hash, newCapacity);
				e.next = newTable[i];
				newTable[i] = e;
				e = next;
			} while (e != null);
		}
	}
}

7:获得元素

public V get(Object key) {
	if (key == null)
		return getForNullKey();
	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;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值