搜尋
首頁Javajava教程Java中ArrayList初始化容量大小為10的原因是什麼

為什麼HashMap的初始化容量為16?

在聊ArrayList的初始化容量時,要先來回顧一下HashMap的初始化容量。這裡以Java 8源碼為例,HashMap中的相關因素有兩個:初始化容量及裝載因子:

/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
 * The load factor used when none specified in constructor.
 */
static final float DEFAULT_LOAD_FACTOR = 0.75f;

在HashMap當中,數組的預設初始化容量為16,當資料填入預設容量的0.75時,就會進行2倍擴容。當然,使用者也可以在初始化時傳入指定大小。但要注意的是,最好是2的n次方的數值,如果未設定為2的n次方,HashMap也會將其轉化,反而多了一步操作。

關於HashMap的實作原理的內容,這裡就不再贅述,網路上已經有太多文章講這個了。有一點我們需要知道的是HashMap計算Key值座標的演算法,也就是透過對Key值進行Hash,進而映射到陣列中的座標。

此時,確保HashMap的容量是2的n次方,那麼在hash運算時就可以採用位元運行直接對記憶體進行操作,無需轉換成十進制,效率會更高。

通常,可以認為,HashMap之所以採用2的n次方,同時預設值為16,有以下方面的考量:

  • # #減少hash碰撞;

  • 提高Map查詢效率;

  • #已分配過小防止頻繁擴充;

  • 分配過大浪費資源;

總之,HashMap之所以採用16作為預設值,是為了減少hash碰撞,同時提升效率。

ArrayList的初始化容量是10嗎?

下面,先來確認ArrayList的初始化容量是不是10,然後在討論為什麼是這個值。

先來看看Java 8中,ArrayList初始化容量的原始碼:

/**
 * Default initial capacity.
 */
private static final int DEFAULT_CAPACITY = 10;

很明顯,預設的容器初始化值為10。而且從JDK1.2到JDK1.6,這個數值也總是都是10。

從JDK1.7開始,在初始化ArrayList的時候,預設值初始化為空數組:

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

此處肯定有朋友說,Java 8中ArrayList默認初始化大小為0,不是10。而且也會發現構造方法上的註解有些奇怪:建構一個初始容量10的空列表。什麼鬼?明明是空的啊!

保留疑問,先來看ArrayList的add方法:

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

在add方法中呼叫了ensureCapacityInternal方法,進入該方法一開始是一個空容器所以

size=0傳入的minCapacity=1

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

上述方法先透過calculateCapacity來計算容量:

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

會發現

minCapacity被重新賦值為10(DEFAULT_CAPACITY=10),傳入ensureExplicitCapacity(minCapacity);minCapacity=10

##以下是方法體:

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

上述程式碼中grow方法是用來處理擴容的,將容量擴容為原來的1.5倍。

了解上面的處理流程,我們會發現,本質上ArrayList的初始化容量還是10,只不過使用懶加載而已,這是Java 8為了節省記憶體而進行的優化而已。所以,自始至終,ArrayList的初始化容量都是10。

這裡再多提一下懶載入的好處,當有成千上萬的ArrayList存在程式當中,10個物件的預設大小意味著在建立時為底層陣列分配10個指標(40 或80位元組)並用空值填充它們,一個空數組(用空值填充)佔用大量記憶體。如果能夠延遲初始化數組,那麼就能夠節省大量的記憶體空間。 Java 8的改動就是出於上述目的。

為什麼ArrayList的初始化容量為10?

最後,我們來探討為什麼ArrayList的初始化容量為10。其實,可以說沒有為什麼,就是「感覺」10挺好的,不大不小,剛剛好,眼緣!

首先,在討論HashMap的時候,我們說到HashMap之所以選擇2的n次方,更多的是考慮到hash演算法的效能與碰撞等問題。這個問題對於ArrayList的來說並不存在。 ArrayList只是一個簡單的成長陣列,不用考慮演算法層面的最佳化。只要超過一定的數值,進行成長即可。所以,理論上來講ArrayList的容量是任何正值即可。

ArrayList的文檔中並沒有說明為什麼選擇10,但很大的可能是出於性能損失與空間損失之間的最佳匹配考慮。 10,不是很大,也不是很小,不會浪費太多的記憶體空間,也不會折損太多效能。

如果要問當初到底為什麼選擇10,可能只有問這段程式碼的作者「Josh Bloch」了吧。

如果你仔細觀察,還會發現一些其他有趣的初始化容量數字:

ArrayList-10
Vector-10
HashSet-16
HashMap-16
HashTable-11

ArrayList與Vector初始化容量一樣,為10;HashSet、HashMap初始化容量一樣,為16;而HashTable獨獨使用11,又是一個很有意思的問題。

以上是Java中ArrayList初始化容量大小為10的原因是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
Java開發的哪些方面取決於平台?Java開發的哪些方面取決於平台?Apr 26, 2025 am 12:19 AM

JavadevelovermentIrelyPlatForm-DeTueTososeVeralFactors.1)JVMVariationsAffectPerformanceNandBehaviorAcroSsdifferentos.2)Nativelibrariesviajnijniiniininiinniinindrododerplatefform.3)

在不同平台上運行Java代碼時是否存在性能差異?為什麼?在不同平台上運行Java代碼時是否存在性能差異?為什麼?Apr 26, 2025 am 12:15 AM

Java代碼在不同平台上運行時會有性能差異。 1)JVM的實現和優化策略不同,如OracleJDK和OpenJDK。 2)操作系統的特性,如內存管理和線程調度,也會影響性能。 3)可以通過選擇合適的JVM、調整JVM參數和代碼優化來提升性能。

Java平台獨立性有什麼局限性?Java平台獨立性有什麼局限性?Apr 26, 2025 am 12:10 AM

Java'splatFormentenceHaslimitations不包括PerformanceOverhead,versionCompatibilityIsissues,挑戰WithnativelibraryIntegration,Platform-SpecificFeatures,andjvminstallation/jvminstallation/jvmintenance/jeartenance.therefactorscomplicatorscomplicatethe“ writeOnce”

解釋平台獨立性和跨平台發展之間的差異。解釋平台獨立性和跨平台發展之間的差異。Apr 26, 2025 am 12:08 AM

PlatformIndependendecealLowsProgramStormonanyPlograwsStormanyPlatFormWithOutModification,而LileCross-PlatFormDevelopmentRequiredquiresMomePlatform-specificAdjustments.platFormIndependence,EneblesuniveByjava,EnablesuniversUniversAleversalexecutionbutmayCotutionButMayComproMisePerformance.cross.cross.cross-platformd

即時(JIT)彙編如何影響Java的性能和平台獨立性?即時(JIT)彙編如何影響Java的性能和平台獨立性?Apr 26, 2025 am 12:02 AM

JITcompilationinJavaenhancesperformancewhilemaintainingplatformindependence.1)Itdynamicallytranslatesbytecodeintonativemachinecodeatruntime,optimizingfrequentlyusedcode.2)TheJVMremainsplatform-independent,allowingthesameJavaapplicationtorunondifferen

為什麼Java是開發跨平台桌面應用程序的流行選擇?為什麼Java是開發跨平台桌面應用程序的流行選擇?Apr 25, 2025 am 12:23 AM

javaispopularforcross-platformdesktopapplicationsduetoits“ writeonce,runany where”哲學。 1)itusesbytiesebyTecodeThatrunsonAnyJvm-備用Platform.2)librarieslikeslikeslikeswingingandjavafxhelpcreatenative-lookingenative-lookinguisis.3)

討論可能需要在Java中編寫平台特定代碼的情況。討論可能需要在Java中編寫平台特定代碼的情況。Apr 25, 2025 am 12:22 AM

在Java中編寫平台特定代碼的原因包括訪問特定操作系統功能、與特定硬件交互和優化性能。 1)使用JNA或JNI訪問Windows註冊表;2)通過JNI與Linux特定硬件驅動程序交互;3)通過JNI使用Metal優化macOS上的遊戲性能。儘管如此,編寫平台特定代碼會影響代碼的可移植性、增加複雜性、可能帶來性能開銷和安全風險。

與平台獨立性相關的Java開發的未來趨勢是什麼?與平台獨立性相關的Java開發的未來趨勢是什麼?Apr 25, 2025 am 12:12 AM

Java將通過雲原生應用、多平台部署和跨語言互操作進一步提昇平台獨立性。 1)雲原生應用將使用GraalVM和Quarkus提升啟動速度。 2)Java將擴展到嵌入式設備、移動設備和量子計算機。 3)通過GraalVM,Java將與Python、JavaScript等語言無縫集成,增強跨語言互操作性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中