日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

注:本文所有代碼示例均基于 JDK8。

從源碼出發(fā)

默認(rèn)值

通過查看 HashMap 的源碼可以得知其默認(rèn)的初始容量為 16,默認(rèn)的加載因子為 0.75。

/**
 * The default initial capacity - MUST be a power of two.
 * 默認(rèn)的初始容量(必須是2的N次冪),默認(rèn)為2^4=16
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
 * The load factor used when none specified in constructor.
 * 默認(rèn)的加載因子為0.75
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;

構(gòu)造方法

/**
 * Constructs an empty <tt>HashMap</tt> with the specified initial
 * capacity and load factor.
 *
 * @param initialCapacity the initial capacity
 * @param loadFactor the load factor
 * @throws IllegalArgumentException if the initial capacity is negative
 * or the load factor is nonpositive
 */
public HashMap(int initialCapacity, float loadFactor) {
		if (initialCapacity < 0)
				throw new IllegalArgumentException("Illegal initial capacity: " +
																					 initialCapacity);
		if (initialCapacity > MAXIMUM_CAPACITY)
				initialCapacity = MAXIMUM_CAPACITY;
		if (loadFactor <= 0 || Float.isNaN(loadFactor))
				throw new IllegalArgumentException("Illegal load factor: " +
																					 loadFactor);
		this.loadFactor = loadFactor;
		this.threshold = tableSizeFor(initialCapacity);
}
/**
 * Constructs an empty <tt>HashMap</tt> with the specified initial
 * capacity and the default load factor (0.75).
 *
 * @param initialCapacity the initial capacity.
 * @throws IllegalArgumentException if the initial capacity is negative.
 */
public HashMap(int initialCapacity) {
		this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
/**
 * Constructs an empty <tt>HashMap</tt> with the default initial capacity
 * (16) and the default load factor (0.75).
 */
public HashMap() {
		this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}

一般情況下都是通過這三種構(gòu)造方法來初始化 HashMap 的。通過默認(rèn)的無參構(gòu)造方法初始化后 HashMap 的容量就是默認(rèn)的16,加載因子也是默認(rèn)的0.75;通過帶參數(shù)的構(gòu)造方法可以初始化一個(gè)自定義容量和加載因子的 HashMap。通常情況下,加載因子使用默認(rèn)的0.75就好。

初始容量

HashMap 的容量要求必須是2的N次冪,這樣可以提高散列的均勻性,降低 Hash 沖突的風(fēng)險(xiǎn)。但是容量可以通過構(gòu)造方法傳入的,如果我傳入一個(gè)非2次冪的數(shù)進(jìn)去呢?比如3?傳進(jìn)去也不會(huì)干嘛呀,又不報(bào)錯(cuò)。。。哈哈哈哈。 是的,不會(huì)報(bào)錯(cuò)的,那是因?yàn)?HashMap 自己將這個(gè)數(shù)轉(zhuǎn)成了一個(gè)最接近它的2次冪的數(shù)。這個(gè)轉(zhuǎn)換的方法是 tableSizeFor(int cap) 。

/**
 * Returns a power of two size for the given target capacity.
 */
static final int tableSizeFor(int cap) {
		int n = cap - 1;
		n |= n >>> 1;
		n |= n >>> 2;
		n |= n >>> 4;
		n |= n >>> 8;
		n |= n >>> 16;
		return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

這個(gè)方法會(huì)將傳入的數(shù)轉(zhuǎn)換成一個(gè)2次冪的數(shù),比如傳入的是3,則返回的是4;傳入12,則返回的是16。

加載因子

加載因子和 HashMap 的擴(kuò)容機(jī)制有著非常重要的聯(lián)系,它可以決定在什么時(shí)候才進(jìn)行擴(kuò)容。HashMap 是通過一個(gè)閥值來確定是否擴(kuò)容,當(dāng)容量超過這個(gè)閥值的時(shí)候就會(huì)進(jìn)行擴(kuò)容,而加載因子正是參與計(jì)算閥值的一個(gè)重要屬性,閥值的計(jì)算公式是 容量 * 加載因子。如果通過默認(rèn)構(gòu)造方法創(chuàng)建 HashMap ,則閥值為 16 * 0.75 = 12 ,就是說當(dāng) HashMap 的容量超過12的時(shí)候就會(huì)進(jìn)行擴(kuò)容。

/**
 * The next size value at which to resize (capacity * load factor).
 *
 * @serial
 */
int threshold;

這是 HashMap 的 putVal(...) 方法的一個(gè)片段,put(...) 方法其實(shí)就是調(diào)用的這個(gè)方法,size 是當(dāng)前 HashMap 的元素個(gè)數(shù),當(dāng)元素個(gè)數(shù)+1后超過了閥值就會(huì)調(diào)用 resize() 方法進(jìn)行擴(kuò)容。

if (++size > threshold)
		resize();

加載因子在一般情況下都最好不要去更改它,默認(rèn)的0.75是一個(gè)非常科學(xué)的值,它是經(jīng)過大量實(shí)踐得出來的一個(gè)經(jīng)驗(yàn)值。當(dāng)加載因子設(shè)置的比較小的時(shí)候,閥值就會(huì)相應(yīng)的變小,擴(kuò)容次數(shù)就會(huì)變多,這就會(huì)導(dǎo)致 HashMap 的容量使用不充分,還沒添加幾個(gè)值進(jìn)去就開始進(jìn)行了擴(kuò)容,浪費(fèi)內(nèi)存,擴(kuò)容效率還很低;當(dāng)加載因子設(shè)置的又比較大的時(shí)候呢,結(jié)果又很相反,閥值變大了,擴(kuò)容次數(shù)少了,容量使用率又提高了,看上去是很不錯(cuò),實(shí)際上還是有問題,因?yàn)槿萘渴褂玫脑蕉啵琀ash 沖突的概率就會(huì)越大。所以,選擇一個(gè)合適的加載因子是非常重要的。

實(shí)踐檢驗(yàn)真理

默認(rèn)無參構(gòu)造方法測試

通過默認(rèn)構(gòu)造方法創(chuàng)建一個(gè) HashMap,并循環(huán)添加13個(gè)值

HashMap的初始容量和加載因子

 

當(dāng)添加第1個(gè)值后,容量為16,加載因子為0.75,閥值為12

HashMap的初始容量和加載因子

 

當(dāng)添加完第13個(gè)值后,執(zhí)行了擴(kuò)容操作,容量變?yōu)榱?2,加載因子不變,閥值變?yōu)榱?4

HashMap的初始容量和加載因子

 

有參構(gòu)造方法測試-只設(shè)置初始容量

創(chuàng)建一個(gè)初始容量為12(非2次冪數(shù))的 HashMap,并添加1個(gè)值

HashMap的初始容量和加載因子

 

創(chuàng)建一個(gè)初始容量為2的 HashMap,并添加2個(gè)值

HashMap的初始容量和加載因子

 

當(dāng)添加完第1個(gè)值后,容量為2,加載因子為0.75,閥值為1

HashMap的初始容量和加載因子

 

當(dāng)添加完第2個(gè)值后,執(zhí)行了擴(kuò)容操作,容量變?yōu)?,加載因子為0.75,閥值為3

HashMap的初始容量和加載因子

 

有參構(gòu)造方法測試-設(shè)置初始容量和加載因子

創(chuàng)建一個(gè)初始容量為2、加載因子為1的 HashMap,并添加2個(gè)值

HashMap的初始容量和加載因子

 

當(dāng)添加完第1個(gè)值后,容量為2,加載因子為1,閥值為2

HashMap的初始容量和加載因子

 

當(dāng)添加完第2個(gè)值后,并沒有執(zhí)行擴(kuò)容操作,容量、加載因子、閥值均沒有變化

HashMap的初始容量和加載因子

 

分享到:
標(biāo)簽:HashMap
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績?cè)u(píng)定