国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

HashMap的擴容機制、初始化容量大小的選擇、容量為什么是2的次冪

這篇具有很好參考價值的文章主要介紹了HashMap的擴容機制、初始化容量大小的選擇、容量為什么是2的次冪。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前置知識

先來看看HashMap中的成員屬性

HashMap的擴容機制、初始化容量大小的選擇、容量為什么是2的次冪

解釋:

  • size當(dāng)前的容器中Entry的數(shù)量,也就是當(dāng)前K-V的數(shù)量
  • loadFactory裝載因子,用來衡量HashMap滿的程度,loadFactory的默認值是0.75
  • threshold臨界值,當(dāng)實際KV數(shù)量超過threshold時,就會觸發(fā)擴容機制。
    threshold = capatity * loadFactory

容量capatity

除了以上這些成員屬性外,還有一個緊密關(guān)聯(lián)的概念:capatity容量。
capatity與size不是同一個概念,size來表示當(dāng)前的HashMap已經(jīng)裝了多少,capatity是容量,HashMap最多能裝多少

利用反射獲取HashMap的容量capatity的大小
看好這個方法,接下來要用

public static void printHashMapCapacity(HashMap map) throws Exception {  
    Class<? extends HashMap> mapClass = map.getClass();  
    Method capacity = mapClass.getDeclaredMethod("capacity");  
    capacity.setAccessible(true);  
    Integer invoke = (Integer) capacity.invoke(map);  
    System.out.println(invoke);  
}

如果利用HashMap的無參構(gòu)造,默認情況下的容量是16,當(dāng)達到擴容機制時,就會擴容到32,以此類推
如果在new時,指定容量大小,則HashMap會選擇第一個大于等于此數(shù)字的2的冪次作為初始容量

HashMap<Object, Object> hashMap = new HashMap<>();  
printHashMapCapacity(hashMap);  
// 默認的容量16  
  
HashMap<Object, Object> map2 = new HashMap<>(1);  
printHashMapCapacity(map2);  
// 1 , 因為2的0次方是1  
  
HashMap<Object, Object> map3 = new HashMap<>(7);  
printHashMapCapacity(map3);  
// 8 , 第一個大于7的2的次冪是8

阿里Java開發(fā)手冊中規(guī)定,在初始化HashMap時,應(yīng)該盡量指定其初始大小

loadFactory和threshold

這兩個屬性用來指定HashMap的擴容機制
threshold = loadFactory * capacity
當(dāng)HashMap中的size超過threshold時,就會觸發(fā)擴容,每次擴容后的容量是原始容量的2倍
從默認的初始容量16擴容到32、64、128…
loadFactory是裝載因子,用來衡量HashMap滿的程度,默認值是0.75f。
設(shè)置成0.75的好處是:capacity是2的次冪,兩個數(shù)的乘積還是整數(shù),避免浮點數(shù)造成影響。
我們初始化HashMap時,除了可以指定初始化容量大小外,還可以指定裝載因子的大小的,但是修改裝載因子的值是不推薦的。

為什么要設(shè)置初始化容量

當(dāng)HashMap 發(fā)生擴容時,會新建一個指定容量的桶,然后將原來的Entry拷貝到新的桶中。
此過程會有較大的資源消耗。
為了避免在向HashMap中put過多元素時頻繁發(fā)生擴容,需要指定一個合適大小的初始化容量。

初始化容量設(shè)置多少合適

我們的目的是避免頻繁發(fā)生擴容,所以一次性指定初始化容量合適大小。
并不是我要塞入多少個元素,就初始化為多少,來看一個例子:
當(dāng)我要向HashMap中put 7個元素,我將HashMap初始化為7

HashMap map = new HashMap(7);

因為傳入的是一個7,HashMap會選擇一個大于等于該值的2的次冪作為容量capacity
根據(jù)loadFactory=0.75,計算出threshold = 8 * 0.75 = 6
當(dāng)我們put第7個元素時,就會觸發(fā)擴容,擴容到16。
但是我們就想put 7個元素,在第7個時觸發(fā)擴容,導(dǎo)致了性能和空間的浪費。
所以,我們在初始化時,選擇多少的初始化容量,值得考慮。

借鑒HashMap 中putAll()方法,得出以下公式:

initCapatity = expectedSize / 0.75F + 1.0F 

這個計算方法雖然浪費了一些空間,但是在性能上卻提升了。
當(dāng)我們要put 7個元素, initCapacity = 7 / 0.75 + 1 = 10 ,經(jīng)過HashMap的計算,第一個大于10的2的次冪的數(shù)是16,所以HashMap的容量是16。
16 * 0.75 = 12 ,當(dāng)我要put第7個元素時,并不會發(fā)生擴容,性能得到提升。
而且與第一次我們設(shè)置初始化容量為7相比,最終所占用的空間是一樣的。

為什么選擇2的次冪作為容量

因為,在put時,HashMap會根據(jù)key的hash來計算對應(yīng)Entry所在桶的位置。
通常都是利用求余來實現(xiàn)的

index = hash % capacity

但是直接利用%來計算是非常慢的,效率非常第低。
我們知道,在計算機中,最快的運算就是位運算了。
存在這樣一個規(guī)律:當(dāng)capacity是2的次冪時,滿足以下恒等式

hash % capacity == hash & (capacity - 1)

在我們創(chuàng)建HashMap時,就做了第一步處理,選擇大于等于給定數(shù)字的第一個2的次冪作為容量,就保證了。文章來源地址http://www.zghlxwxcb.cn/news/detail-426007.html

到了這里,關(guān)于HashMap的擴容機制、初始化容量大小的選擇、容量為什么是2的次冪的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機制及中斷回調(diào)機制詳解

    STM32使用HAL庫中外設(shè)初始化MSP回調(diào)機制及中斷回調(diào)機制詳解

    在STM32的HAL庫使用中,會發(fā)現(xiàn)庫函數(shù)大都被設(shè)計成了一對: HAL_PPP/PPPP_Init HAL_PPP/PPPP_MspInit 而且HAL_PPP/PPPP_MspInit函數(shù)的defination前面還會有__weak 上面的PPP/PPPP代表常見外設(shè)的名稱為3個字符或者4個字符 怎么理解這個設(shè)計呢? 2.1 結(jié)論 首先說結(jié)論: HAL_PPP/PPPP_Init 是與具體芯片

    2024年02月13日
    瀏覽(45)
  • SpringBoot 底層機制分析【Tomcat 啟動+Spring 容器初始化+Tomcat 如何關(guān)聯(lián)Spring 容器】【下】

    SpringBoot 底層機制分析【Tomcat 啟動+Spring 容器初始化+Tomcat 如何關(guān)聯(lián)Spring 容器】【下】

    ??前言 本篇博文是關(guān)于SpringBoot 底層機制分析實現(xiàn),希望能夠幫助你更好的了解SpringBoot ?? ??個人主頁:晨犀主頁 ??個人簡介:大家好,我是晨犀,希望我的文章可以幫助到大家,您的滿意是我的動力???? ??歡迎大家:這里是CSDN,我總結(jié)知識的地方,歡迎來到我的博客

    2024年02月13日
    瀏覽(28)
  • Docker 制作 MySQL 鏡像并使用 `/docker-entrypoint-initdb.d/` 機制初始化數(shù)據(jù)

    Docker 制作 MySQL 鏡像并使用 `/docker-entrypoint-initdb.d/` 機制初始化數(shù)據(jù)

    制作一個 MySQL Docker 鏡像并初始化數(shù)據(jù)庫信息 win 11 Docker-Desktop 4.14.0 (91374) 啟動一個MySQL容器很容易。如何初始化數(shù)據(jù)呢? 大概我們會嘗試很多操作,比如百度常見到 使用 CMD 命令調(diào)用shell腳本,通過shell腳本處理初始化數(shù)據(jù)等等,經(jīng)過實踐,這些都不太方便。 其實,MySQL 官方提

    2024年01月18日
    瀏覽(852)
  • HashMap原理(三):容量、加載因子、大小的含義

    /* Copyright ? 1997, 2013, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 only, as published by the Free Software Foundation. Oracle designates this particular file

    2024年02月07日
    瀏覽(21)
  • Pytorch權(quán)重初始化/參數(shù)初始化

    refer: 【Pytorch】各網(wǎng)絡(luò)層的默認初始化方法 https://blog.csdn.net/guofei_fly/article/details/105109883 其實Pytorch初始化方法就在各自的層的 def reset_parameters(self) - None: 方法中。 有人可能會問 為什么這個方法和Pytorch直接出來的權(quán)重初始值不一樣 ?單步調(diào)試會發(fā)現(xiàn)其實這個方法運行了至少兩

    2024年02月11日
    瀏覽(32)
  • Linux內(nèi)存初始化-啟動階段的內(nèi)存初始化

    Linux內(nèi)存初始化-啟動階段的內(nèi)存初始化

    本文代碼基于ARM64平臺, Linux kernel 5.15 在加載kernel 之前, kernel對于系統(tǒng)是有一定要求的,明確規(guī)定了boot階段必須要把MMU關(guān)閉: 那么在進入kernel之后, 就必須有一個使能MMU, 建立映射的過程, 本文描述kernel啟動階段進行內(nèi)存初始化相關(guān)的操作。 在初始化階段,我們mapping二段

    2024年02月08日
    瀏覽(25)
  • 【溫故而知新】JavaScript初始化/初始化加載

    在JavaScript中,對象、數(shù)組、函數(shù)、類等都可以通過不同的方式進行初始化。以下是幾種常見的初始化方式: 對象初始化: 使用字面量方式: 使用構(gòu)造函數(shù)方式: 數(shù)組初始化: 使用字面量方式: 使用構(gòu)造函數(shù)方式: 函數(shù)初始化: 類初始化: 使用Array的of和from方法進行數(shù)組

    2024年01月24日
    瀏覽(92)
  • 深度學(xué)習(xí)參數(shù)初始化(二)Kaiming初始化 含代碼

    深度學(xué)習(xí)參數(shù)初始化(二)Kaiming初始化 含代碼

    目錄 一、介紹 二、基礎(chǔ)知識 三、Kaiming初始化的假設(shè)條件? 四、Kaiming初始化的簡單的公式推導(dǎo) 1.前向傳播 2.反向傳播 五、Pytorch實現(xiàn) 深度學(xué)習(xí)參數(shù)初始化系列: (一)Xavier初始化 含代碼 (二)Kaiming初始化 含代碼 ????????Kaiming初始化論文地址:https://arxiv.org/abs/1502.01

    2024年02月04日
    瀏覽(19)
  • 【隨機種子初始化】一個神經(jīng)網(wǎng)絡(luò)模型初始化的大坑

    【隨機種子初始化】一個神經(jīng)網(wǎng)絡(luò)模型初始化的大坑

    半年前寫了一個模型,取得了不錯的效果(簡稱項目文件1),于是整理了一番代碼,保存為了一個新的項目(簡稱項目文件2)。半年后的今天,我重新訓(xùn)練這個整理過的模型,即項目文件2,沒有修改任何的超參數(shù),并且保持完全一致的隨機種子,但是始終無法完全復(fù)現(xiàn)出半

    2024年02月09日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包