1. 程式人生 > >ArrayList初始化容量的問題

ArrayList初始化容量的問題

(所有的圖片的程式碼來源於JDK1.8中的原始碼)

可能很多同學聽到網上其他人說ArrayList的底層陣列elementData的初始化容量是10。

其實並不是!,下圖是我們經常初始化ArrayList使用的構造器:
這裡寫圖片描述
而DEFAULTCAPACITY_EMPTY_ELEMENTDATA也是一個空的陣列,請看下面的圖示:
這裡寫圖片描述

說白了就是,每次我們呼叫初始化一個空白的集合ArrayList,它的底層陣列其實是空的。那人們說的初始化容量是10到底是從哪來的呢?

其實是:當我們第一次為ArrayList新增元素的時候,底層陣列擴容到了10。

下面我們就分析一下這個過程:

當我們通過ArrayList呼叫add()方法新增元素的時候,其實底層一共需要呼叫了4個方法(如果需要擴容的話,則呼叫5個方法。Math.max()和Arrays.copyOf()不計入其內。)下面先給出原始碼檢視,然後我們一一分析程式碼:

首先假設我們使用ArrayList<Integer> arrayList = new ArrayList<>();構造的是一個空的ArrayList,此時ArrayList底層的elementData是一個DEFAULTCAPACITY_EMPTY_ELEMENTDATA(上面有原始碼)。

接著呼叫了ensureCapacityInternal,然後引數size+1,也就是1(size代表我們集合中元素的個數)。
這裡寫圖片描述

接著呼叫calculateCapacity(計算容量),通過判斷elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA(也就是判斷我們在初始化ArrayList的時候,是不是使用的是預設的構造器),如果是初始化的時候使用的是預設的狗再去,接著就返回DEFAULT_CAPACITY和上面我們傳的引數中的最大值,而DEFAULT_CAPACITY在原始碼就是我們常說的初始化容量10,此時該方法返回DEFAULT_CAPACITY,如果不是使用預設構造器初始化的話,則直接返回我們傳入的引數(也就是我們一開始的size+1)。

到目前為止我們的底層陣列elementData的容量仍然是0,並沒有進行擴容,接著呼叫ensureExplicitCapacity()方法,在該方法內部首先呼叫modCount++表明此刻在修改ArrayList如果不懂modCount的含義,你可以看我的另一篇部落格ArrayList原始碼解析
裡面有講到modCount。接著判斷一下:如果我們傳進來的引數minCapacity(size+1)大於我們當前底層陣列elementData的長度(此時為0),則需要擴容,接著呼叫了grow()方法進行了擴容。
這裡寫圖片描述

在grow()方法中,首先通過將element的容量擴容至原來的1.5倍(有時是小於1.5倍)(同時這裡也是ArrayList的自動擴容機制),接著判斷如果擴容後的容量仍舊小於minCapacity,就把minCapacity作為新容量,否則什麼也不做,接著判斷如果新容量大於最大陣列容量的話,繼續呼叫hugeCapacity()進行擴容(一般呼叫這個的話會爬出異常),最後通過Arrays.copyOf()進行陣列的擴容。


這裡寫圖片描述

相關推薦

ArrayList初始容量的問題

(所有的圖片的程式碼來源於JDK1.8中的原始碼) 可能很多同學聽到網上其他人說ArrayList的底層陣列elementData的初始化容量是10。 其實並不是!,下圖是我們經常初始化ArrayList使用的構造器: 而DEFAULTCAPA

ArrayList初始預設容量(長度)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

關於HashMap初始容量問題

使用阿里雲程式碼規範外掛掃描後出現以下提示: hashmap should set a size when initalizing,即hashmap應該在初始化時設定一個大小 今天看到美團招聘給出了一道小題目,關於HashMap的效能問題。問題如下: java ha

Java : ArrayList 初始及賦值的兩種方式

package com.idark; import java.util.ArrayList; /** * @description: Demo測試 * @author: iDark * @create: 2018/8/3 14:57 * @email:

阿里巴巴Java開發手冊建議建立HashMap時設定初始容量,但是多少合適呢?

集合是Java開發日常開發中經常會使用到的,而作為一種典型的K-V結構的資料結構,HashMap對於Java開發者一定不陌生。 關於HashMap,很多人都對他有一些基本的瞭解,比如他和hashtable之間的區別、他和concurrentHashMap之間的區別等。這些都是比較常見的,關於HashMap的一

JAVA中初始ArrayList的三種方式

  下面講一下ArrayList初始化的幾種不同方式。   一、最常用的初始化方式。 1 List<String> list1 = new ArrayList<String>(); 2 list1.add("apple"); 3 lis

關於HashMap容量初始,還有這麼多學問。

在《HashMap中傻傻分不清楚的那些概念》文章中,我們介紹了HashMap中和容量相關的幾個概念,簡單介紹了一下HashMap的擴容機制。 文中我們提到,預設情況下HashMap的容量是16,但是,如果使用者通過建構函式指定了一個數字作為容量,那麼Hash會選

java之ArrayList初始容量原始碼解析【jdk 1.8】

ArrayList解析 繼承的類和實現的介面 public class ArrayList<E>extends AbstractList<E>implements List<

STM32F10xx(高容量)WiFi模組的初始和使用

本次實驗是使用每次傳輸不超過200B的ESP8266晶片的WiFi模組,WiFi模組內部自有驅動,我們初始化它,只需要傳送指定的指令給他就可以了,指定的指令其實是使用USART3的複用的PB10和PB11進行通訊, 首先看原理圖管腳連線 下載文件,閱讀大概的WiFi指令有哪些,並且返回什麼 【E

初始ArrayList的兩種方法

方式一:  ArrayList<String> list = new ArrayList<String>();  String str01 = String("str01");  String str02 = String("str02");  li

ArrayList初始容量對效能的影響

package testList; import java.util.ArrayList; public class TestLArrayList { public static void main(String[] args) { System.out.prin

初始ArrayList、List的兩種方法

說明: 個人偏向第二種方法,適合沒有伺服器資料的情況下,做個簡單的list來開發 方式一: ArrayList<String> list = new ArrayList<Str

C# ArrayList初始和常用方法和查詢元素

ArrayList的定義和初始化如下: ArrayList的常用方法如下: List.Add(100)---往List陣列中新增元素100 List.Insert(3,100)---往List索引為3的位置插入100 List.InsertRange(3, Lis

ArrayList的四種初始方法

1.使用Arrays.asList方法 ArrayList<Type> obj = new ArrayList<Type>(Arrays.asList(Object o1, Object o2, Object o3, ....so on)); 舉個

ArrayList,HashMap,LinkedList 初始大小和 擴容機制

前面寫這篇文章的時候,看的是JDK1.6,然後就被下面的評論的人噴成了垃圾,是我沒有說明清楚。 1.ArrayList jdk1.6 的原始碼 /** * Constructs an empty list with the specified init

java怎麼用一行程式碼初始ArrayList

其實,可能要初始化的"最佳"方式,ArrayList 是你寫的方法,因為它不需要建立一個新的 List 以任何方式: ArrayList<String> list = new ArrayList<String>(); list.add("A"); list.add(

初始ArrayList的簡單方法總結

方法1ArrayList<String> places = new ArrayList<String>(Arrays.asList("Buenos Aires", "Córdob

java中hashmap容量初始

HashMap使用HashMap(int initialCapacity)對集合進行初始化。 在預設的情況下,HashMap的容量是16。但是如果使用者通過建構函式指定了一個數字作為容量,那麼Hash會選擇大於該數字的第一個2的冪作為容量。比如如果指定了3,則容量是4;如果指定了7,則容量是8;如果指定了9

Linux下C結構體初始

直觀 tro 擴展性 方式 建議 struct 初始化方式 www 寫到 原文地址在這裏: http://www.cnblogs.com/Anker/p/3545146.html 我 只把裏面的主要介紹和代碼寫到這裏了. 順序初始化   教科書上講C語言結構體初始化

java學習筆記——java中對象的創建,初始,引用的解析

初始 學習筆記 style article 學習 base 表達 如果 bsp 如果有一個A類。 1、例如以下表達式: A a1 = new A(); 那麽A是類,a1是引用。new A()是對象。僅僅是a1這個引用指向了new A()這個對象。 2、又如: A