最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中Arraylist動態(tài)擴容方法詳解

 更新時間:2017年08月28日 10:48:48   作者:適AT  
ArrayList的列表對象實質(zhì)上是存儲在一個引用型數(shù)組里的,下面這篇文章主要給大家介紹了關于Java中Arraylist動態(tài)擴容方法的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。

前言

本文主要給大家介紹了關于Java中Arraylist動態(tài)擴容的相關內(nèi)容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。

ArrayList 概述

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

動態(tài)擴容

一 初始化

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

public ArrayList();

默認的構(gòu)造器,將會以默認的大小來初始化內(nèi)部的數(shù)組

public ArrayList(Collection<? extends E> c)

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

public ArrayList(int initialCapacity) 

用指定的大小來初始化內(nèi)部的數(shù)組

后兩種方式都可以理解,通過創(chuàng)造對象,或指定大小來初始化內(nèi)部數(shù)據(jù)即可。

那我們來重點關注一下無參數(shù)構(gòu)造器的實現(xiàn)過程:

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

 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

可以看出它的默認數(shù)組為長度為0。而在之前JDK1,6中,無參數(shù)構(gòu)造器代碼是初始長度為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 方法中。我們來看一下具體實現(xiàn)。

二  確保內(nèi)部容量

我們以無參數(shù)構(gòu)造為例, 初始化時,數(shù)組長度為0. 那我現(xiàn)在要添加數(shù)據(jù)了,數(shù)組的長度是怎么變化的?

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

① ensureCapacityInternal方法名的英文大致是“確保內(nèi)部容量”,size表示的是執(zhí)行添加之前的元素個數(shù),并非ArrayList的容量,容量應該是數(shù)組elementData的長度。ensureCapacityInternal該方法通過將現(xiàn)有的元素個數(shù)數(shù)組的容量比較??慈绻枰獢U容,則擴容。

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

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

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

  ensureExplicitCapacity(minCapacity);
 }

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

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

三 擴容

/*
 *增加容量,以確保它至少能容納
 *由最小容量參數(shù)指定的元素數(shù)。
 * @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這里增加了對元素個數(shù)的最大個數(shù)判斷,jdk1.7以前是沒有最大值判斷的,MAX_ARRAY_SIZE 為int最大值減去8(不清楚為什么用這個值做比較)
  if (newCapacity - MAX_ARRAY_SIZE > 0)
   newCapacity = hugeCapacity(minCapacity);
  // 最重要的復制元素方法
  elementData = Arrays.copyOf(elementData, newCapacity);
 }

綜上所述,ArrayList相當于在沒指定initialCapacity時就是會使用延遲分配對象數(shù)組空間,當?shù)谝淮尾迦朐貢r才分配10(默認)個對象空間。假如有20個數(shù)據(jù)需要添加,那么會分別在第一次的時候,將ArrayList的容量變?yōu)?0 (如下圖一);之后擴容會按照1.5倍增長。也就是當添加第11個數(shù)據(jù)的時候,Arraylist繼續(xù)擴容變?yōu)?0*1.5=15(如下圖二);當添加第16個數(shù)據(jù)時,繼續(xù)擴容變?yōu)?5 * 1.5 =22個(如下圖四)。:

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

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

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

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

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

對比和總結(jié):

本文介紹了 ArrayList動態(tài)擴容的全過程。如果通過無參構(gòu)造的話,初始數(shù)組容量為0,當真正對數(shù)組進行添加時,才真正分配容量。每次按照1.5倍(位運算)的比率通過copeOf的方式擴容。 在JKD1.6中實現(xiàn)是,如果通過無參構(gòu)造的話,初始數(shù)組容量為10,每次通過copeOf的方式擴容后容量為原來的1.5倍,以上就是動態(tài)擴容的原理。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

參考資料:http://blog.csdn.net/u010176014/article/details/52073339

相關文章

  • spring boot使用sharding jdbc的配置方式

    spring boot使用sharding jdbc的配置方式

    這篇文章主要介紹了spring boot使用sharding jdbc的配置方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • JAVA代理,靜態(tài),動態(tài)詳解

    JAVA代理,靜態(tài),動態(tài)詳解

    這篇文章主要介紹了Java靜態(tài)代理和動態(tài)代理總結(jié),非常不錯,具有參考借鑒價值,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09
  • SpringBoot2零基礎到精通之數(shù)據(jù)庫專項精講

    SpringBoot2零基礎到精通之數(shù)據(jù)庫專項精講

    SpringBoot是一種整合Spring技術棧的方式(或者說是框架),同時也是簡化Spring的一種快速開發(fā)的腳手架,本篇我們來學習如何連接數(shù)據(jù)庫進行操作
    2022-03-03
  • vue2向springboot傳值接收不到的解決方法

    vue2向springboot傳值接收不到的解決方法

    本文主要介紹了vue2向springboot傳值接收不到的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • java高級用法之綁定CPU的線程Thread?Affinity簡介

    java高級用法之綁定CPU的線程Thread?Affinity簡介

    java線程thread affinity是用來將java代碼中的線程綁定到CPU特定的核上,用來提升程序運行的性能,這篇文章主要介紹了java高級用法之綁定CPU的線程thread affinity的相關知識,需要的朋友可以參考下
    2022-05-05
  • Java?GenericObjectPool?對象池化技術之SpringBoot?sftp?連接池工具類詳解

    Java?GenericObjectPool?對象池化技術之SpringBoot?sftp?連接池工具類詳解

    這篇文章主要介紹了Java?GenericObjectPool?對象池化技術之SpringBoot?sftp?連接池工具類詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Java8中的 Lambda表達式教程

    Java8中的 Lambda表達式教程

    這篇文章主要介紹了 Java8中的 Lambda表達式教程,需要的朋友可以參考下
    2017-02-02
  • Java8中List轉(zhuǎn)換String字符串幾種方式

    Java8中List轉(zhuǎn)換String字符串幾種方式

    這篇文章主要給大家介紹了關于Java8中List轉(zhuǎn)換String字符串的幾種方式,在實際開發(fā)中經(jīng)常遇到List轉(zhuǎn)為String字符串的情況,文中給出了幾種方法的示例代碼,需要的朋友可以參考下
    2023-07-07
  • 關于Seata基本使用及二階提交流程

    關于Seata基本使用及二階提交流程

    這篇文章主要介紹了關于Seata基本使用及二階提交流程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Data Source與數(shù)據(jù)庫連接池簡介(JDBC簡介)

    Data Source與數(shù)據(jù)庫連接池簡介(JDBC簡介)

    DataSource是作為DriverManager的替代品而推出的,DataSource 對象是獲取連接的首選方法,這篇文章主要介紹了Data Source與數(shù)據(jù)庫連接池簡介(JDBC簡介),需要的朋友可以參考下
    2022-11-11

最新評論

玉门市| 明水县| 吕梁市| 九龙县| 景谷| 香河县| 抚州市| 崇左市| 佛坪县| 呈贡县| 陕西省| 河池市| 仙桃市| 孝昌县| 黑河市| 元朗区| 荥经县| 都昌县| 乐清市| 洛浦县| 夹江县| 潞城市| 平武县| 宿迁市| 琼海市| 星座| 衡南县| 出国| 上蔡县| 张家川| 宁阳县| 米林县| 左权县| 齐齐哈尔市| 辰溪县| 甘泉县| 白河县| 芜湖县| 揭阳市| 定日县| 同德县|