• 走一次HashMap的存取


    忘了太多东西,好好复习。

    存:

     1 if ((tab = table) == null || (n = tab.length) == 0)
     2             n = (tab = resize()).length;//检查容器大小
     3         if ((p = tab[i = (n - 1) & hash]) == null)
     4             tab[i] = newNode(hash, key, value, null); //无冲突
     5         else {
     6             Node<K,V> e; K k;
     7             if (p.hash == hash &&
     8                 ((k = p.key) == key || (key != null && key.equals(k))))//每次都判断桶头
     9                 e = p;                                                     
    10             else if (p instanceof TreeNode)
    11                 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); //如果当前的桶转化成红黑树,调用红黑树的插入方法
    12             else {
    13                 for (int binCount = 0; ; ++binCount) { //遍历桶
    14                     if ((e = p.next) == null) {
    15                         p.next = newNode(hash, key, value, null);//桶末尾插入
    16                         if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
    17                             treeifyBin(tab, hash);//桶的大小大于阈值(8)将该桶转化为红黑树
    18                         break;
    19                     }
    20                     if (e.hash == hash &&
    21                         ((k = e.key) == key || (key != null && key.equals(k))))      
    22                         break;//找到桶中存在的Node
    23                     p = e;
    24                 }
    25             }
    26         ...
    27 }

    取:

     1 final Node<K,V> getNode(int hash, Object key) {
     2         Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
     3         if ((tab = table) != null && (n = tab.length) > 0 &&
     4             (first = tab[(n - 1) & hash]) != null) {
     5             if (first.hash == hash && // always check first node
     6                 ((k = first.key) == key || (key != null && key.equals(k))))
     7                 return first;
     8             if ((e = first.next) != null) {
     9                 if (first instanceof TreeNode)
    10                     return ((TreeNode<K,V>)first).getTreeNode(hash, key);      //找树
    11                 do {
    12                     if (e.hash == hash &&
    13                         ((k = e.key) == key || (key != null && key.equals(k))))  //找桶
    14                         return e;
    15                 } while ((e = e.next) != null);
    16             }
    17         }
    18         return null;
    19     }

    Java 8的HashMap的存储从 数组+链表(桶)变成了 数组+(链表/红黑树)。

    1 if (p instanceof TreeNode)
    2     ...

    所以它的基本操作中都会出现这样的代码片段。

    因为这样的改动使得在Hash值相同的容器比较大的时候,它的查找效率不会退化成线性表地查询log(n)。

  • 相关阅读:
    Python学习札记(十五) 高级特性1 切片
    LeetCode Longest Substring Without Repeating Characters
    Python学习札记(十四) Function4 递归函数 & Hanoi Tower
    single number和变体
    tusen 刷题
    实验室网站
    leetcode 76. Minimum Window Substring
    leetcode 4. Median of Two Sorted Arrays
    leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions 、434. Number of Islands II(lintcode) 并查集 、178. Graph Valid Tree(lintcode)
    刷题注意事项
  • 原文地址:https://www.cnblogs.com/jason-koo/p/11266129.html
Copyright © 2020-2023  润新知