Map
interface Map<K, V>
将键映射到值的对象。
V put(K key, V value) 将指定的值与该映射中的指定键相关联
void putAll(Map<? extends K,? extends V> m) 将指定地图的所有映射复制到此映射 default boolean replace(K key, V oldValue, V newValue) 仅当当前映射到指定的值时,才能替换指定键的条目。
default void replaceAll(BiFunction<? super K,? super V,? extends V> function) 将每个条目的值替换为对该条目调用给
定函数的结果,直到所有条目都被处理或该函数抛出异常。
V remove(Object key) 如果存在(从可选的操作),从该地图中删除一个键的映射。
default boolean remove(Object key, Object value) 仅当指定的密钥当前映射到指定的值时删除该条目。
V get(Object key) 返回到指定键所映射的值,或 null如果此映射包含该键的映射。
boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。
boolean containsValue(Object value) 如果此地图将一个或多个键映射到指定的值,则返回 true 。
Set<Map.Entry<K,V>> entrySet() 返回此地图中包含的映射的Set视图。
Set<K> keySet() 返回此地图中包含的键的Set视图。
Collection<V> values() 返回此地图中包含的值的Collection视图。
void clear() 从该地图中删除所有的映射(可选操作)。
boolean isEmpty() 如果此地图不包含键值映射,则返回 true 。
int size() 返回此地图中键值映射的数量。
HashMap
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
基于哈希表的实现的Map接口,此实现提供了所有可选的地图操作,并允许null的值和null键。
构造函数 容量是哈希表中的桶数,初始容量只是创建哈希表时的容量. (容量就是数组length) 负载因子是在容量自动增加之前允许哈希表得到满足的度量.
static final float DEFAULT_LOAD_FACTOR = 0.75f; //负载因子
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //容量 默认值16
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
table entrySet size
transient Node<K,V>[] table; // 存放数据的数组
transient Set<Map.Entry<K,V>> entrySet;//迭代器操作的Set集合
transient int size; //存放键值对的个数
static class Node<K,V> implements Map.Entry<K,V> {
final int hash; // 计算过的hash 1 -16 之间取值
final K key; //key 值
V value; //value 值
Node<K,V> next; //下一个Node数据
}
V put(K key, V value)
将指定的值与该映射中的指定键相关联
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
// ^ (h >>> 16) 之后 hashCode 不变
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
// tab 该Map的数据数组 p遍历的Node n tab的length i 数组位置
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0) tab是否为bull
n = (tab = resize()).length; //为空 用resize初始化 tab = new Node[16]; n=16
if ((p = tab[i = (n - 1) & hash]) == null) //tab[hash]是否有Node 赋值p
// (n-1)&hash取值为0 ~ 数组长度之间
tab[i] = newNode(hash, key, value, null);//没有Node 要添加的Node放入
else {
Node<K,V> e; K k;
// 要加入的Node 是否等于 该数组下标的第一个Node
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p; // 等于 e = p
else if (p instanceof TreeNode) 忽略
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
//遍历hash对应的链表 如果有重复的Node 停止循环 不加入 没有则加到链表的末尾
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) { // 遍历的Node 下一个Node是null 赋值
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
// 判断该链表是否有重复的Node 有 停止循环
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
return oldValue;
}
}
++modCount;
if (++size > threshold) // size到一定大小 需要扩容
resize();
afterNodeInsertion(evict);
return null;
}
Node<K,V>[] resize() 假如table 为null tab[] 长度为16 扩容界限为12 ( size大于这个数量就调用size()扩容 ) 不为null length = length * 2 (32... ) 扩容界限= threshold *2 (24 ..)
final Node<K,V>[] resize() {
Node<K,V>[] oldTab = table;
int oldCap = (oldTab == null) ? 0 : oldTab.length;//现在tab的length
int oldThr = threshold; //
int newCap, newThr = 0;
if (oldCap > 0) { // tab 是否为空
if (oldCap >= MAXIMUM_CAPACITY) { // 已经是最大值 返回现有table
threshold = Integer.MAX_VALUE;
return oldTab;
}
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY) //容量大于16 小于最大 并且x2
newThr = oldThr << 1; //界限x2
}
else if (oldThr > 0)
newCap = oldThr;
else { //table为空 lenth 为16 下一个扩容数量界限是12 16*0.75 12
newCap = DEFAULT_INITIAL_CAPACITY; // 16
newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);//12
}
if (newThr == 0) { // 如果table 不为空 下一个扩容计算
float ft = (float)newCap * loadFactor;
newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
(int)ft : Integer.MAX_VALUE);
}
threshold = newThr;
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
... table不为空 复制值
return newTab;
}
final Node<K,V> removeNode(int hash, Object key, Object value,boolean matchValue, boolean movable)
matchValue 如果值相等,则只有真值 movable 如果是假,在移除时不要移动其他节点
final Node<K,V> removeNode(int hash, Object key, Object value,
boolean matchValue, boolean movable) {
Node<K,V>[] tab; Node<K,V> p; int n, index;
if ((tab = table) != null && (n = tab.length) > 0 &&
(p = tab[index = (n - 1) & hash]) != null) { //tab是否为空 frist是否为null
Node<K,V> node = null, e; K k; V v;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))//frist是否是该Node
node = p;
else if ((e = p.next) != null) { //遍历链表 找到要删除的Node 赋值给node变量
if (p instanceof TreeNode)
node = ((TreeNode<K,V>)p).getTreeNode(hash, key);
else {
do {
if (e.hash == hash &&
((k = e.key) == key ||
(key != null && key.equals(k)))) {
node = e;
break;
}
p = e;// 如果不是该节点赋值给p p是上个Node e是该Node
} while ((e = e.next) != null);
}
}
if (node != null && (!matchValue || (v = node.value) == value ||
(value != null && value.equals(v)))) {
if (node instanceof TreeNode)
((TreeNode<K,V>)node).removeTreeNode(this, tab, movable);
else if (node == p) //frist 是该节点
tab[index] = node.next;
else
p.next = node.next; //
++modCount;
--size;
afterNodeRemoval(node);
return node;
}
}
return null;
}
boolean replace(K key, V oldValue, V newValue)
仅当当前映射到指定的值时,才能替换指定键的条目。
@Override
public V replace(K key, V value) {
Node<K,V> e;
if ((e = getNode(hash(key), key)) != null) { //获取数组中该key value对应的节点
V oldValue = e.value;
e.value = value; //把原来的Node中Value 赋值新Value
afterNodeAccess(e); //子类重写该方法
return oldValue;
}
return null;
}
Node<K,V> getNode(int hash, Object key) 根据hashKey去找到 Node
final Node<K,V> getNode(int hash, Object key) {
// frist 数组位置第一个Node
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) { // tab是否为空 frist Node 是否为空
// frist 是查找的节点
if (first.hash == hash &&
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) { //frist next Node 是否为空
if (first instanceof TreeNode) //忽略
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do { //
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e; // 对比key 形同返回Value
} while ((e = e.next) != null); // 循环遍历
}
}
return null;
}
public V get(Object key)
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
boolean containsKey(Object key)
此Map是否包含该key
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
boolean containsValue(Object value
)
此Map是否包含该Value
public boolean containsValue(Object value) {
Node<K,V>[] tab; V v;
if ((tab = table) != null && size > 0) { //tab 是否为空
for (int i = 0; i < tab.length; ++i) { //遍历tab
for (Node<K,V> e = tab[i]; e != null; e = e.next) { //遍历链表
if ((v = e.value) == value ||
(value != null && value.equals(v))) //对比value
return true;
}
}
}
return false;
}
Set<Map.Entry<K,V>> entrySet()
返回了一个EntrySet 类 详情见下
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}
EntrySet
final class EntrySet extends AbstractSet<Map.Entry<K,V>>
泛型 Map.Entry<K,V>
能把map转化为set的工具类
final Iterator<Map.Entry<K,V>> iterator() 迭代器 EntryIterator见下
public final Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();
}
final boolean contains(Object o) 传入的对象必须是 MapEntry
public final boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Node<K,V> candidate = getNode(hash(key), key); // 通过key 去Map里面查找Value
//? 没有通过getValue()
return candidate != null && candidate.equals(e);
}
final boolean remove(Object o) 传入的对象必须是 MapEntry
public final boolean remove(Object o) {
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Object value = e.getValue(); //用Map的remove删除
return removeNode(hash(key), key, value, true, true) != null;
}
return false;
}
EntryIterator
final class EntryIterator extends HashIterator implements Iterator<Map.Entry<K,V>> HashIterator
abstract class HashIterator next 调用的时候HashIterator nextNode方法
final class EntryIterator extends HashIterator
implements Iterator<Map.Entry<K,V>> {
public final Map.Entry<K,V> next() { return nextNode(); }
}
HashIterator
next current
Node<K,V> next; // 下一个返回的node
Node<K,V> current; // 当前node (已经返回的Node)
构造方法 Next = index[0] 中的第一个节点
HashIterator() { //
expectedModCount = modCount;
Node<K,V>[] t = table;
current = next = null;
index = 0;
// 遍历 找到frist Node不为空的Node 然后next赋值
if (t != null && size > 0) { // next table[0] 第一个node
do {} while (index < t.length && (next = t[index++]) == null);
}
}
Node<K,V> nextNode() if()判断 加入next不为空 就直接返回当前next 为空就去移动到下一个table的坐标 然后找到不为空节点 返回
final Node<K,V> nextNode() {
Node<K,V>[] t;
Node<K,V> e = next;
// next 为空 就通过while找下一个frist不为空的链表
if ((next = (current = e).next) == null && (t = table) != null) {
do {} while (index < t.length && (next = t[index++]) == null);
}
return e;
}
public final void remove() 移除当前节点
public final void remove() {
Node<K,V> p = current;
current = null; // 当前Node 赋null
K key = p.key;
removeNode(hash(key), key, null, false, false); //删除该Node
expectedModCount = modCount;
}
public Set<K> keySet() 通过KeySet类实现 见下
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();
keySet = ks;
}
return ks;
}
KeySet
final class KeySet extends AbstractSet<K>
public final Iterator<K> iterator() 迭代器 KeyIterator见下
public final Iterator<K> iterator() { return new KeyIterator(); }
KeyIterator
final class KeyIterator extends HashIterator
next() 遍历的是 HashIterator 的NextNode方法
final class KeyIterator extends HashIterator
implements Iterator<K> {
public final K next() { return nextNode().key; }
}
public Collection<V> values() Values 详情见下
public Collection<V> values() {
Collection<V> vs = values;
if (vs == null) {
vs = new Values();
values = vs;
}
return vs;
}
Values
final class Values extends AbstractCollection<V>
public final Iterator<V> iterator()
public final Iterator<V> iterator() { return new ValueIterator(); }
ValueIterator
final class ValueIterator extends HashIterator
public final V next()
final class ValueIterator extends HashIterator
implements Iterator<V> {
public final V next() { return nextNode().value; }
}