HashMap的putVal函式原始碼解析
/** * The default initial capacity - MUST be a power of two. */ // 預設容量16 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 /** * The load factor used when none specified in constructor. */ // 預設載入因子 // 如果size大於載入因子*容量,將擴容resize() static final float DEFAULT_LOAD_FACTOR = 0.75f;
put呼叫的是putVal
/** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, the old * value is replaced. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with <tt>key</tt>, or * <tt>null</tt> if there was no mapping for <tt>key</tt>. * (A <tt>null</tt> return can also indicate that the map * previously associated <tt>null</tt> with <tt>key</tt>.) */ public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
putVal
/** * Implements Map.put and related methods * * @param hash hash for key * @param key the key * @param value the value to put * @param onlyIfAbsent if true, don't change existing value * @param evict if false, the table is in creation mode. * @return previous value, or null if none */ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; // 判斷HashMap的Node陣列是否為空 if ((tab = table) == null || (n = tab.length) == 0) // 如果為空,則初始化陣列 n = (tab = resize()).length; // 判斷HashMap的Node陣列的hash位置是否為空 if ((p = tab[i = (n - 1) & hash]) == null) // 如果為空直接插入一個節點 tab[i] = newNode(hash, key, value, null); // 如果不為空 else { Node<K,V> e; K k; // 當前Node的Key和新插入的Key是否相等 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) // 直接覆蓋 e = p; // 當前Node是否為紅黑樹的TreeNode else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); // 當前Node是否為單向連結串列的Node else { // 遍歷單向連結串列 for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); // 如果雜湊衝突(雜湊碰撞)的數量大於等於8,將單向連結串列轉換為紅黑樹 // 當執行treeifyBin(tab, hash);的時候,也不一定必須轉換成紅黑樹 // 如果一個Node的單向連結串列的長度小於64,擴容 // 如果一個Node的單向連結串列的長度大於等於64,才將此單向連結串列轉換成紅黑樹 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } // 當前Node的Key和新插入的Key是否相等 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } // 判斷新插入的Node是否已存在,如果已存在根據onlyIfAbsent是否用新值覆蓋舊值 if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; // 擴容 if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }
相關推薦
HashMap的putVal函式原始碼解析
/** * The default initial capacity - MUST be a power of two. */ // 預設容量16 static final int DEFAULT_INITIAL_CAPACITY
jQuery原始碼解析:變數與函式
//原始碼剖析都基於jQuery-2.0.3版本,主要考慮到相容IE 2行:jQuery javaScript Library v2.0.3——jQuery版本 3行:http://jQuery.com——官網 5~6行:Includes Sizzle.js;http://sizzlejs.
redis原始碼解析(二)動態字串sds基本功能函式
1. 簡介 本文繼上文基礎上,分析動態字串的功能函式,位於sds.c。由於函式較多,本篇介紹實現動態變化的基本增刪新建釋放函式。 2. 原始碼分析 sdsHdrSize()函式用於返回sdshdr的大小,主要使用sizeof()函式實現。 /*返回sds
Java原始碼解析HashMap的tableSizeFor函式
aka,HashMap的容量大小必須為2的指數,即16,32,64,128這樣的值。那麼,在建構函式中,如果呼叫者指定了HashMap的初始大小不是2的指數,那麼,HashMap的tableSizeFor函式,會計算一個大於或等於給定引數的2的指數的值。先來看一下tableSizeFor函式的原始碼
underscore.js原始碼解析之函式繫結
1. 引言 underscore.js是一個1500行左右的Javascript函式式工具庫,裡面提供了很多實用的、耦合度極低的函式,用來方便的操作Javascript中的陣列、物件和函式,它支援函式式和麵向物件鏈式的程式設計風格,還提供了一個精巧的模板引
Spring原始碼解析——從XmlBeanFactory的建構函式開始看LoadBeanDefinitions
之前的文章聊過ClassPathResource類,通過這個類,我們從classpath載入到了我們的spring配置檔案,之後,就開始執行XmlBeanFactory的構造過程了:public XmlBeanFactory(Resource resource
Spring IOC原理原始碼解析(@Autowired原理詳解 :標識建構函式)(一 )
IOC,inversion of control 控制反轉,有時候也叫DI,dependency injection 依賴注入,是一種程式碼解耦的方式。 在一個類中定義一個屬性,正常情況下需要在此類中有對此屬性賦值的程式碼,如setter方法,或者在建構函式中
原始碼解析: Imread函式
在第一篇處,我們只是在最表層的上面操作函式,當別人問我們時,我們其實什麼也不知道的。就知道,imread是讀取函數了,然後掉用其它的函式的樂樂。當然,上面我們可以好好學習人家為什麼要這樣做了!這裡,看一個函式finddecoder()。這個函式主要是獲取decoder物件,從而決定讀取什麼樣字尾名的影象(j
caffe原始碼解析之cblas函式
Y(vetor)←αAX + βY This function multiplies A * X (after transposing A, if needed) and multiplies the resulting matrix by alpha. It then multiplies vector
pinpoint 原始碼解析,怎樣監控tornado 協程中的函式?
## 協程中監控函式,為啥比較特殊! 首先需要明白pinpoint 怎樣做監控的。 1. python中通過包裝器,實現函式/方法包裝 2. pinpoint內部維持一個呼叫棧的關係,內部通過棧來實現。這個棧的生命期和函式執行的生命期繫結在一起。 然而, 協程函式可以被yeild,await 中斷。
yolo v2 損失函式原始碼解讀
前提說明: 1, 關於 yolo 和 yolo v2 的詳細解釋請移步至如下兩個連結,或者直接看論文(我自己有想寫 yolo 的教程,但思前想後下面兩個連結中的文章質量實在是太好了_(:з」∠)_) yo
Netty進階:Futrue&Promise原始碼解析
文章目錄 1. Future&Promise 2. AbstractFuture 3.Completefuture 4.Channelfuture&Completechannel
大資料基礎(1)zookeeper原始碼解析
五 原始碼解析 public enum ServerState { LOOKING, FOLLOWING, LEADING, OBSERVING;}zookeeper伺服器狀態:剛啟動LOOKING,follower是FOLLOWING,leader是LEADING,observer是
Android框架原始碼解析之(四)Picasso
這次要分析的原始碼是 Picasso 2.5.2 ,四年前的版本,用eclipse寫的,但不影響這次我們對其原始碼的分析 地址:https://github.com/square/picasso/tree/picasso-parent-2.5.2 Picasso的簡單使用
Android框架原始碼解析之(三)ButterKnife
注:所有分析基於butterknife:8.4.0 原始碼目錄:https://github.com/JakeWharton/butterknife 其中最主要的3個模組是: Butterknife註解處理器https://github.com/JakeWharton/
Android框架原始碼解析之(二)OKhttp
原始碼在:https://github.com/square/okhttp 包實在是太多了,OKhttp核心在這塊https://github.com/square/okhttp/tree/master/okhttp 直接匯入Android Studio中即可。 基本使用:
Android框架原始碼解析之(一)Volley
前幾天面試CVTE,HR面掛了。讓內部一個學長幫我查看了一下面試官評價,發現二面面試官的評價如下: 廣度OK,但缺乏深究能力,深度與實踐不足 原始碼:只能說流程,細節程式碼不清楚,retrofit和volley都是。 感覺自己一方面:自己面試技巧有待提高吧(框
HashMap原始碼解析(JDK8)
前言 這段時間有空,專門填補了下基礎,把常用的ArrayList、LinkedList、HashMap、LinkedHashMap、LruCache原始碼看了一遍,List相對比較簡單就不單獨介紹了,Map準備用兩篇的篇幅,分別介紹HashMap和(LruCache+LinkedHa
原始碼解析--Long、long型別的比較遇到的問題
Long、long型別的比較遇到的問題: 1、long 是基本型別 Long是物件型別。 public static void main(String[] args) { Long A = 127l; Long B = 127l; long C = 127; l
CopyOnWriteArrayList實現原理以及原始碼解析
CopyOnWriteArrayList實現原理以及原始碼解析 1、CopyOnWrite容器(併發容器) Copy-On-Write簡稱COW,是一種用於程式設計中的優化策略。 其基本思路是,從一開始大家都在共享同一個內容,當某個人想要修改這個內容的時候,才