欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

本文主要給大家介紹了關(guān)于Java中Arraylist動(dòng)態(tài)擴(kuò)容的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。

ArrayList 概述

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

動(dòng)態(tài)擴(kuò)容

一 初始化

首先有三種方式來(lái)初始化:

public ArrayList();

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

public ArrayList(Collection<? extends E> c)

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

public ArrayList(int initialCapacity) 

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

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

那我們來(lái)重點(diǎn)關(guān)注一下無(wú)參數(shù)構(gòu)造器的實(shí)現(xiàn)過(guò)程:

/**
  * 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 = {};

可以看出它的默認(rèn)數(shù)組為長(zhǎng)度為0。而在之前JDK1,6中,無(wú)參數(shù)構(gòu)造器代碼是初始長(zhǎng)度為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];
 }

接下來(lái),要擴(kuò)容的話,肯定是在ArrayList.add 方法中。我們來(lái)看一下具體實(shí)現(xiàn)。

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

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

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

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

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

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

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

  ensureExplicitCapacity(minCapacity);
 }

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

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

三 擴(kuò)容

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

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

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

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

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

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

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

對(duì)比和總結(jié):

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

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

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

相關(guān)文章

  • 解決spring jpa中update的坑

    解決spring jpa中update的坑

    這篇文章主要介紹了spring jpa中update遇到的坑及解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 基于Process#waitFor()阻塞問(wèn)題的解決

    基于Process#waitFor()阻塞問(wèn)題的解決

    這篇文章主要介紹了Process#waitFor()阻塞問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java代碼抓取網(wǎng)頁(yè)郵箱的實(shí)現(xiàn)方法

    java代碼抓取網(wǎng)頁(yè)郵箱的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇java代碼抓取網(wǎng)頁(yè)郵箱的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • JavaWeb中的filter過(guò)濾敏感詞匯案例詳解

    JavaWeb中的filter過(guò)濾敏感詞匯案例詳解

    敏感詞、文字過(guò)濾是一個(gè)網(wǎng)站必不可少的功能,本篇文章主要介紹了JavaWeb中的filter過(guò)濾敏感詞匯案例,具有一定的參考價(jià)值,有需要的可以了解一下,
    2016-11-11
  • java文件刪除不了File類(lèi)的delete方法刪不掉文件的原因以及分析

    java文件刪除不了File類(lèi)的delete方法刪不掉文件的原因以及分析

    這篇文章主要介紹了java文件刪除不了File類(lèi)的delete方法刪不掉文件的原因以及分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Swing常用組件之多行文本區(qū)JTextArea

    Swing常用組件之多行文本區(qū)JTextArea

    這篇文章主要為大家詳細(xì)介紹了Swing常用組件之多行文本區(qū)JTextArea,感興趣的朋友可以參考一下
    2016-05-05
  • Java和Redis實(shí)現(xiàn)熱搜功能

    Java和Redis實(shí)現(xiàn)熱搜功能

    這篇文章主要介紹了Java和Redis實(shí)現(xiàn)熱搜功能,在存儲(chǔ)和傳輸用戶(hù)搜索數(shù)據(jù)時(shí),考慮到數(shù)據(jù)的機(jī)密性和隱私保護(hù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • 簡(jiǎn)單談?wù)凷pring Ioc原理解析

    簡(jiǎn)單談?wù)凷pring Ioc原理解析

    學(xué)習(xí)過(guò)Spring框架的人一定都會(huì)聽(tīng)過(guò)Spring的IoC(控制反轉(zhuǎn)) 、DI(依賴(lài)注入)這兩個(gè)概念,對(duì)于初學(xué)Spring的人來(lái)說(shuō),總覺(jué)得IoC 、DI這兩個(gè)概念是模糊不清的,是很難理解的,今天和大家分享網(wǎng)上的一些技術(shù)大牛們對(duì)Spring框架的IOC的理解以及談?wù)勎覍?duì)Spring Ioc的理解。
    2018-09-09
  • SpringBoot中Shiro緩存使用Redis、Ehcache的方法

    SpringBoot中Shiro緩存使用Redis、Ehcache的方法

    這篇文章主要介紹了SpringBoot中Shiro緩存使用Redis、Ehcache的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • java  StringBuilder類(lèi)的詳解及簡(jiǎn)單實(shí)例

    java StringBuilder類(lèi)的詳解及簡(jiǎn)單實(shí)例

    這篇文章主要介紹了java StringBuilder類(lèi)的詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,實(shí)現(xiàn)了StringBuilder類(lèi)的追加、插入、替換、刪除等操作,需要的朋友可以參考下
    2017-08-08

最新評(píng)論