10)replaceAll(BiFunction<? super K, ? super V, ? extends V> function);//替换新值
/** * 根据lambda函数替换符合规则的值 */ @Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { Node<K,V>[] tab; if (function == null) throw new NullPointerException(); if (size > 0 && (tab = table) != null) { int mc = modCount; for (int i = 0; i < tab.length; ++i) { for (Node<K,V> e = tab[i]; e != null; e = e.next) { e.value = function.apply(e.key, e.value); } } if (modCount != mc) throw new ConcurrentModificationException(); } }总结:
正常情况下会扩容2倍,特殊情况下(新扩展数组大小已经达到了最大值)则只取最大值1 << 30。
1)V remove(Object key); //根据key 删除元素
/** * 根据key 删除元素 */ public V remove(Object key) { Node<K,V> e; return (e = removeNode(hash(key), key, null, false, true)) == null ? null : e.value; } /** * Implements Map.remove and related methods * * @param hash hash for key * @param key the key * @param value the value to match if matchValue, else ignored * @param matchValue if true only remove if value is equal * @param movable if false do not move other nodes while removing * @return the node, or null if none */ 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) { Node<K,V> node = null, e; K k; V v; if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) node = p; else if ((e = p.next) != null) { 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; } 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) tab[index] = node.next; else p.next = node.next; ++modCount; --size; afterNodeRemoval(node); return node; } } return null; }2)remove(Object key, Object value); //根据key,value 删除元素
/** * 根据key,value 删除元素 */ @Override public boolean remove(Object key, Object value) { return removeNode(hash(key), key, value, true, true) != null; } 3.get方法(2种实现)--查 /** * 返回指定的值 */ public V get(Object key) { Node<K,V> e; return (e = getNode(hash(key), key)) == null ? null : e.value; } /** * @author jiaxiaoxian * @date 2019年2月12日 * 如果key不为空则返回key的值,否则返回默认值 */ @Override public V getOrDefault(Object key, V defaultValue) { Node<K,V> e; return (e = getNode(hash(key), key)) == null ? defaultValue : e.value; } 4.keySet方法--返回所有key,以Set结构返回 /** * 返回所有key,以Set结构返回 */ public Set<K> keySet() { Set<K> ks; return (ks = keySet) == null ? (keySet = new KeySet()) : ks; } 5.clone方法--克隆 /** * 复制,返回此HashMap 的浅拷贝 */ @SuppressWarnings("unchecked") @Override public Object clone() { HashMap<K,V> result; try { result = (HashMap<K,V>)super.clone(); } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } result.reinitialize(); result.putMapEntries(this, false); return result; } 7.clear方法--清空HashMap /** * 清空HashMap */ public void clear() { Node<K,V>[] tab; modCount++; if ((tab = table) != null && size > 0) { size = 0; for (int i = 0; i < tab.length; ++i) tab[i] = null; } } 8.containsKey方法--是否存在此key /** * 是否存在此key */ public boolean containsKey(Object key) { return getNode(hash(key), key) != null; } 9.containsValue方法--是否存在此value /** * 是否存在此value */ public boolean containsValue(Object value) { Node<K,V>[] tab; V v; if ((tab = table) != null && size > 0) { for (int i = 0; i < tab.length; ++i) { for (Node<K,V> e = tab[i]; e != null; e = e.next) { if ((v = e.value) == value || (value != null && value.equals(v))) return true; } } } return false; } 10.entrySet方法--返回key,value的Set结果 /** * 返回key,value的Set结果 */ public Set<Map.Entry<K,V>> entrySet() { Set<Map.Entry<K,V>> es; return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; } HashMap总结 1)HashMap的key、value都可以存放null,key不可重复,value可重复,是数组链表红黑树的数据结构。 2)HashMap区别于数组的地方在于能够自动扩展大小,其中关键的方法就是resize()方法,扩容为2倍。 3)HashMap由于本质是数组,在不冲突的情况下,查询效率很高,hash冲突后会形成链表,查找时多一层遍历,当链表长度到8并且数组长度大于64,转成红黑树存储,提高查询效率。 4)初始化数组时推荐给初始长度,反复扩容会增加时耗,影响性能效率,HashMap需要注意负载因子0.75f,初始16,当长度大于(16*0.75)12的时候会扩容为32,所以初始长度设置需要却别对待。©著作权归作者所有:来自51CTO博客作者jiazhipeng12的原创作品,如需转载,请注明出处,否则将追究法律责任