中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

在Java項目中怎么對Arraylist進行動態擴容

發布時間:2020-12-02 17:29:49 來源:億速云 閱讀:248 作者:Leah 欄目:編程語言

本篇文章為大家展示了在Java項目中怎么對Arraylist進行動態擴容,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

ArrayList 概述

ArrayList是基于數組實現的,是一個動態數組,其容量能自動增長。ArrayList不是線程安全的,只能用在單線程環境下。實現了Serializable接口,因此它支持序列化,能夠通過序列化傳輸;實現了RandomAccess接口,支持快速隨機訪問,實際上就是通過下標序號進行快速訪問;實現了Cloneable接口,能被克隆。

動態擴容

一 初始化

首先有三種方式來初始化:

public ArrayList();

默認的構造器,將會以默認的大小來初始化內部的數組

public ArrayList(Collection<&#63; extends E> c)

用一個ICollection對象來構造,并將該集合的元素添加到ArrayList

public ArrayList(int initialCapacity) 

用指定的大小來初始化內部的數組

后兩種方式都可以理解,通過創造對象,或指定大小來初始化內部數據即可。

那我們來重點關注一下無參數構造器的實現過程:

/**
  * Constructs an empty list with an initial capacity of ten.
  */
 public ArrayList() {
  // DEFAULTCAPACITY_EMPTY_ELEMENTDATA是空數組
  this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
 }

 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

可以看出它的默認數組為長度為0。而在之前JDK1,6中,無參數構造器代碼是初始長度為10。

JDK6代碼這樣的:

public ArrayList() {
 this(10);
 }
 public ArrayList(int initialCapacity) {
 super();
  if (initialCapacity < 0)
   throw new IllegalArgumentException("Illegal Capacity: "+
            initialCapacity);
 this.elementData = new Object[initialCapacity];
 }

接下來,要擴容的話,肯定是在ArrayList.add 方法中。我們來看一下具體實現。

二  確保內部容量

我們以無參數構造為例, 初始化時,數組長度為0. 那我現在要添加數據了,數組的長度是怎么變化的?

 public boolean add(E e) {
  //確保內部容量(通過判斷,如果夠則不進行操作;容量不夠就擴容來確保內部容量)
  ensureCapacityInternal(size + 1); // ①Increments modCount!!
  elementData[size++] = e;//②
  return true;
 }

① ensureCapacityInternal方法名的英文大致是“確保內部容量”,size表示的是執行添加之前的元素個數,并非ArrayList的容量,容量應該是數組elementData的長度。ensureCapacityInternal該方法通過將現有的元素個數數組的容量比較。看如果需要擴容,則擴容。

②是將要添加的元素放置到相應的數組中。

下面具體看 ensureCapacityInternal(size + 1);

// ① 是如何判斷和擴容的。private void ensureCapacityInternal(int minCapacity) {
  //如果實際存儲數組 是空數組,則最小需要容量就是默認容量
  if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
   minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
  }

  ensureExplicitCapacity(minCapacity);
 }

 private void ensureExplicitCapacity(int minCapacity) {
  modCount++;
  //如果數組(elementData)的長度小于最小需要的容量(minCapacity)就擴容
  if (minCapacity - elementData.length > 0)
   grow(minCapacity);
 }
 /**
  * Default initial capacity.
  */
 private static final int DEFAULT_CAPACITY = 10;

以上,elementData是用來存儲實際內容的數組。minExpand 是最小擴充容量。DEFAULTCAPACITY_EMPTY_ELEMENTDATA共享的空數組實例用于默認大小的空實例。根據傳入的最小需要容量minCapacity來和數組的容量長度對比,若minCapactity大于或等于數組容量,則需要進行擴容。

三 擴容

/*
 *增加容量,以確保它至少能容納
 *由最小容量參數指定的元素數。
 * @param mincapacity所需的最小容量
 */
 private void grow(int minCapacity) {
  // overflow-conscious code
  int oldCapacity = elementData.length;
  //>>位運算,右移動一位。 整體相當于newCapacity =oldCapacity + 0.5 * oldCapacity 
  // jdk1.7采用位運算比以前的計算方式更快
  int newCapacity = oldCapacity + (oldCapacity >> 1);
  if (newCapacity - minCapacity < 0)
   newCapacity = minCapacity;
  //jdk1.7這里增加了對元素個數的最大個數判斷,jdk1.7以前是沒有最大值判斷的,MAX_ARRAY_SIZE 為int最大值減去8(不清楚為什么用這個值做比較)
  if (newCapacity - MAX_ARRAY_SIZE > 0)
   newCapacity = hugeCapacity(minCapacity);
  // 最重要的復制元素方法
  elementData = Arrays.copyOf(elementData, newCapacity);
 }

綜上所述,ArrayList相當于在沒指定initialCapacity時就是會使用延遲分配對象數組空間,當第一次插入元素時才分配10(默認)個對象空間。假如有20個數據需要添加,那么會分別在第一次的時候,將ArrayList的容量變為10 (如下圖一);之后擴容會按照1.5倍增長。也就是當添加第11個數據的時候,Arraylist繼續擴容變為10*1.5=15(如下圖二);當添加第16個數據時,繼續擴容變為15 * 1.5 =22個(如下圖四)。:

向數組中添加第一個元素時,數組容量為10.

在Java項目中怎么對Arraylist進行動態擴容

向數組中添加到第10個元素時,數組容量仍為10.

在Java項目中怎么對Arraylist進行動態擴容

向數組中添加到第11個元素時,數組容量擴為15.

在Java項目中怎么對Arraylist進行動態擴容

向數組中添加到第16個元素時,數組容量擴為22.

在Java項目中怎么對Arraylist進行動態擴容

每次擴容都是通過Arrays.copyOf(elementData, newCapacity) 這樣的方式實現的。

上述內容就是在Java項目中怎么對Arraylist進行動態擴容,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

台北市| 富源县| 色达县| 芜湖县| 句容市| 巴中市| 安乡县| 盐津县| 大港区| 祁门县| 邯郸市| 临沧市| 长宁区| 滨海县| 小金县| 休宁县| 潼南县| 句容市| 阳西县| 清水河县| 边坝县| 海淀区| 偃师市| 白玉县| 峨山| 伊吾县| 黔南| 贞丰县| 红原县| 德昌县| 广州市| 江山市| 综艺| 北流市| 亳州市| 灵寿县| 留坝县| 洪江市| 丹凤县| 白山市| 全州县|