1.数据结构:哈希表(链地址法)
2.默认数组大小:16
3.扩容机制:以原数组2倍方式扩容
4.默认扩容因子:0.75f
5.扩容条件:扩容因子*数组长度
6.线程是否安全:该集合是线程不安全的
7.储存数据类型为键值对(key和value)
8.key和value都可为null
9.key不能重复,value可以重复
10.key相同value进行更新
linkHashMap基本特点:1.key不能重复、value可以重复。
2.linkedHashMap是插入有序的或者访问有序,assessOrder:true访问有序;false插入有序
3.底层的数据结构是哈希表+双向链表
4.key和value都可为null
5.通过linkHashMap继承自HashMap,HashMap的属性及方法被继承,table属性和entry类型都会被继承。
6.linkedHashMap中entry类继承HashMap.Entry,即具有key、value、hash、next等属性,另外新增了两个属性before和after
//头结点 private transient Entryheader; //accessOrder 控制是插入还是访问有序 默认是false即插入有序 ture:访问有序 private final boolean accessOrder; class Entry extends HashMap.Entry { Entry before, after; }
7.linkedHashMap在HashMap的基础上添加一个双向链表。用来记录节点插入顺序(分为访问有序和插入有序与acssessOrder方法的实现有关)
7.1访问有序:每次对哈希表进行访问就将访问节点删除双链表的连接(哈希表结构不变)并添加到双链表最后。
7.2插入有序:只根据插入(也就是put)方法的顺序建立双链表。
//父类HashMap实现
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
//如果table为空,按照默认16大小初始化哈希表
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
linkedhashmap中entry中实现
void recordAccess(HashMap m) {
linkedHashMap lm = (linkedHashMap)m;
if (lm.accessOrder) {
lm.modCount++;
remove();
addBefore(lm.header);
}
}
//如果当前是访问有序,将当前节点从双向链表中删除,然后将其插入head的before处理
//linkedHashmap中实现
void addEntry(int hash, K key, V value, int bucketIndex) {
super.addEntry(hash, key, value, bucketIndex);
// Remove eldest entry if instructed
Entry eldest = header.after;
if (removeEldestEntry(eldest)) {
removeEntryForKey(eldest.key);
}
}
HashMap中addentry
void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}
//linkedHashMap中createEntry
void createEntry(int hash, K key, V value, int bucketIndex) {
HashMap.Entry old = table[bucketIndex];
Entry e = new Entry<>(hash, key, value, old);
table[bucketIndex] = e;
//处理双向链表,插入到header的before位置
e.addBefore(header);
size++;
}



