java--集合--HashMap

Posted 张紫韩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java--集合--HashMap相关的知识,希望对你有一定的参考价值。

  1. HashMap底层机制及源码剖析
    1. 理论:
    2.  源码剖析案例

      1.  

      2. package com.model.map.hashmap;
        
        import java.util.HashMap;
        import java.util.HashSet;
        
        /**
         * @Description:测试类
         * @Author: 张紫韩
         * @Crete 2021/6/14 20:13
         */
        public class HashMapDemo01 {
            public static void main(String[] args) {
                HashMap<Object, Object> hashMap = new HashMap<>();
                hashMap.put("java", "java");
                hashMap.put("php", "a");
                hashMap.put("java", "JAVA");
                System.out.println(hashMap);
        
                /**
                 * 1.执行构造器 new HashMap(),初始化加载因子 loadfactor=0.75 ,HashMap$Node[] table=null
                 *     public HashMap() {
                 *         this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
                 *     }
                 * 2.执行put()
                 *     public V put(K key, V value) {
                 *         return putVal(hash(key), key, value, false, true);
                 *     }
                 *
                 *      2.1 执行hash(key),计算出key的hash值在进行^ (h >>> 16);运算,但会Hash值
                 *             static final int hash(Object key) {
                 *               int h;
                 *               return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
                 *               }
                 *
                 *      2.2执行key.hashCode(),得到hash值
                 *                  public int hashCode() {
                 *         int h = hash;
                 *         if (h == 0 && value.length > 0) {
                 *             char val[] = value;
                 *
                 *             for (int i = 0; i < value.length; i++) {
                 *                 h = 31 * h + val[i];
                 *             }
                 *             hash = h;
                 *         }
                 *         return h;
                 *     }
                 *
                 * 3.执行putVal
                 *
                 *    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                 *                    boolean evict) {
                 *
                 *          //复制变量
                 *         Node<K,V>[] tab; Node<K,V> p; int n, i;
                 *
                 *         //判断是否是第一次添加,如果是就之江将table表扩容到16
                 *         if ((tab = table) == null || (n = tab.length) == 0)
                 *             n = (tab = resize()).length;
                 *
                 *          //通过hash值计算出这个元素应该在表中的那个索引位置,通过索取到这个节点:p
                 *          //如果这 节点为 null,直接将这个元素放在这个节点上,否则进入到else中
                 *         if ((p = tab[i = (n - 1) & hash]) == null)
                 *             tab[i] = newNode(hash, key, value, null);
                 *         else {
                 *
                 *         //定义辅助变量
                 *             Node<K,V> e; K k;
                 *
                 *         //如果p的hash值和要插入的元素相等,且 两个key == 返回rue或者equals()返回true
                 *         //就将 e指向p节点
                 *             if (p.hash == hash &&
                 *                 ((k = p.key) == key || (key != null && key.equals(k))))
                 *                 e = p;
                 *
                 *             //如果p节点上是一个树,则交给putTreeVal  进行添加此元素
                 *             else if (p instanceof TreeNode)
                 *                 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
                 *             else {
                 *
                 *             //如果全上面都不满足,则这是一个链表,则进行循环遍历比较
                 *                 for (int binCount = 0; ; ++binCount) {
                 *
                 *                 //p.next==null说明链表中没有和 要添加的元素一样,直接将这个元素放在链表的末尾
                 *                     if ((e = p.next) == null) {
                 *                         p.next = newNode(hash, key, value, null);
                 *
                 *                         //如果链表长度超过8则进行树化操作
                 *                         if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                 *
                 *                         //树化:需要满组表的长度大于等于64且链表的长度大于8,如果节点数量查过8但表的长度为到64,就不进行树化而是先进行扩容
                 *                             treeifyBin(tab, hash);
                 *                         break;
                 *                     }
                 *
                 *                     //再循环过程中如果 链表中有一个和 要添加的元素相等(即hash值一样且== 或equals()返回true,则跳出循环不在添加)
                 *                     if (e.hash == hash &&
                 *                         ((k = e.key) == key || (key != null && key.equals(k))))
                 *                         break;
                 *                     p = e;
                 *                 }
                 *             }
                 *
                 *             //进行替换操作, 当跳出上面操作时,e正好是和要添加的元素一样的节点
                 *             if (e != null) { // existing mapping for key
                 *                 V oldValue = e.value;
                 *                 if (!onlyIfAbsent || oldValue == null)
                 *
                 *                 //将链表上的节点e的value替换为 要添加元素的value
                 *                     e.value = value;
                 *                 afterNodeAccess(e);
                 *                 return oldValue;
                 *             }
                 *         }
                 *
                 *         ++modCount; //操作数++
                 *         //节点数量加一,判断节点数量是否超过 了临界值
                 *         if (++size > threshold)
                 *             resize();
                 *         afterNodeInsertion(evict);
                 *         return null;
                 *     }
                 *
                 *
                 * */
            }
        }

         

         

          

         

         

         

         

         

            

 

以上是关于java--集合--HashMap的主要内容,如果未能解决你的问题,请参考以下文章

Java集合 -- HashSet 和 HashMap

Java集合系列五HashMap解析

Java集合详解4:HashMap和HashTable

Java并发多线程编程——集合类线程不安全之HashMap的示例及解决方案

Java入门系列之集合HashMap源码分析(十四)

Java 集合框架:HashMap