亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java實(shí)現(xiàn)ArrayList自動(dòng)擴(kuò)容

 更新時(shí)間:2023年12月22日 11:34:09   作者:默o。  
ArrayList的擴(kuò)容規(guī)則是非常簡(jiǎn)單的,它會(huì)根據(jù)需要自動(dòng)擴(kuò)容,本文就來介紹一下Java實(shí)現(xiàn)ArrayList自動(dòng)擴(kuò)容,具有一定的參考價(jià)值,感興趣的可以了解一下

一.為什么要進(jìn)行擴(kuò)容

1.1ArrayLiat底層介紹

ArrayList`是 Java 中的一個(gè)常用集合類,其內(nèi)部實(shí)現(xiàn)是基于數(shù)組的,可以通過下標(biāo)來訪問和修改其中的元素。在操作 `ArrayList` 時(shí),如果我們向其中添加的元素個(gè)數(shù)超過了已分配的數(shù)組長(zhǎng)度,則需要對(duì)數(shù)組進(jìn)行擴(kuò)容。這也是 `ArrayList` 能夠自動(dòng)擴(kuò)容的原因。

1.2擴(kuò)容原因:

下面是對(duì) ArrayList 擴(kuò)容的必要性進(jìn)行解釋:

1. 提高效率

數(shù)組在內(nèi)存中是一段連續(xù)的空間,在同一時(shí)間內(nèi),其所有元素的空間是連續(xù)的。在 `ArrayList` 中,當(dāng)我們需要向其中添加元素時(shí),如果發(fā)現(xiàn)當(dāng)前數(shù)組的長(zhǎng)度已經(jīng)達(dá)到了其最大值,我們就需要對(duì)其進(jìn)行擴(kuò)容。擴(kuò)容的意思是在內(nèi)存中重新分配一個(gè)可以容納更多元素的連續(xù)空間,并將原有數(shù)組的元素復(fù)制到新的空間中。這樣,我們就可以向新的空間中添加元素了。通過擴(kuò)容,我們避免了在數(shù)組中頻繁移動(dòng)元素,提高了程序的效率。

2. 避免數(shù)組下標(biāo)越界

當(dāng)我們?cè)L問數(shù)組時(shí),如果使用的下標(biāo)超出了數(shù)組的實(shí)際長(zhǎng)度,則會(huì)發(fā)生數(shù)組下標(biāo)越界異常。擴(kuò)容可以避免這種情況發(fā)生,因?yàn)閿U(kuò)容會(huì)重新分配更大的內(nèi)存空間,并修改數(shù)組的長(zhǎng)度,使得我們可以在新的空間中添加元素,避免了訪問數(shù)組時(shí)下標(biāo)越界的問題。

3. 降低內(nèi)存碎片

擴(kuò)容可以避免內(nèi)存碎片的產(chǎn)生。在執(zhí)行增刪操作時(shí),如果數(shù)組中存在空洞,即有些位置的元素被刪除后,造成數(shù)組遠(yuǎn)小于原來的大小,這時(shí)也需要重新分配內(nèi)存空間。如果這種情況發(fā)生頻繁,會(huì)導(dǎo)致內(nèi)存空間的碎片化,使得程序性能變差。而數(shù)組的擴(kuò)容操作在內(nèi)存中分配連續(xù)空間,可以避免這種問題的出現(xiàn),從而降低內(nèi)存碎片的產(chǎn)生。

1.3什么是內(nèi)存碎片化?

1.3.1定義:

指在程序運(yùn)行過程中,由于空間的分配和釋放不規(guī)則,形成了很多不連續(xù)、空閑的內(nèi)存片段,使得原本容易找到連續(xù)空間的程序運(yùn)行變得困難。內(nèi)存中的空閑區(qū)域是不連續(xù)的,當(dāng)需要分配一個(gè)大段的內(nèi)存時(shí),就會(huì)因?yàn)檎也坏阶銐虻倪B續(xù)空間而產(chǎn)生問題。這種情況常常發(fā)生在反復(fù)分配和釋放內(nèi)存的場(chǎng)景中,例如大數(shù)據(jù)量的操作或多次執(zhí)行動(dòng)態(tài)數(shù)組擴(kuò)容等。

1.3.2解決方法

內(nèi)存空間的碎片化會(huì)對(duì)系統(tǒng)性能產(chǎn)生負(fù)面影響,因為程序在分配或釋放內(nèi)存時(shí)需要不停地將內(nèi)存碎片合并或分割,這樣會(huì)浪費(fèi)更多的時(shí)間和系統(tǒng)資源。在程序的現(xiàn)代化中,應(yīng)該盡可能地避免或減少內(nèi)存碎片的出現(xiàn),從而優(yōu)化程序性能。

以下是幾種減少內(nèi)存碎片的方法:

  • 使用內(nèi)存池技術(shù),固定分配一部分內(nèi)存塊供程序使用。
  • 動(dòng)態(tài)分配時(shí),采用內(nèi)存對(duì)齊方式,盡量使得分配出來的內(nèi)存塊尺寸是確定的。
  • 盡量減少對(duì)象的分配與回收,從而降低內(nèi)存碎片化的程度。
  • 對(duì)于數(shù)據(jù)結(jié)構(gòu)動(dòng)態(tài)增長(zhǎng)的場(chǎng)景,采用增量式擴(kuò)容的策略,避免一次性分配過大的內(nèi)存空間。

二.進(jìn)行ArrayLiat擴(kuò)容操作

1.擴(kuò)容的底層原理:

ArrayList 自動(dòng)擴(kuò)容的實(shí)現(xiàn):依賴于 `ensureCapacityInternal()` 和 `grow()` 兩個(gè)方法。

當(dāng)添加一個(gè)新元素到 ArrayList 時(shí),ArrayList 會(huì)先判斷當(dāng)前存儲(chǔ)元素的數(shù)組容量是否已經(jīng)達(dá)到了最大大?。?`Integer.MAX_VALUE`),如果已經(jīng)達(dá)到了則不再擴(kuò)容。否則,如果當(dāng)前存儲(chǔ)元素的數(shù)組容量已經(jīng)滿了,那么就需要擴(kuò)容:

1. `ensureCapacityInternal()` 方法會(huì)先計(jì)算出新的容量大小原來的容量大?。ㄓ洖?oldCapacity)加上原來的容量大小的一半(即 oldCapacity >> 1)。
2. 如果新的容量大小小于當(dāng)前所需的容量(即當(dāng)前 arrayList 的大小加 1),則新容量大小為當(dāng)前所需的容量加 1
3. `grow()` 方法會(huì)創(chuàng)建一個(gè)新的存儲(chǔ)元素的數(shù)組,其大小就是新的容量大小。然后它會(huì)調(diào)用 `Arrays.copyOf()` 方法來將舊數(shù)組中的元素復(fù)制到新數(shù)組中。

最后,ArrayList 會(huì)將新的數(shù)組作為內(nèi)部存儲(chǔ)數(shù)組,并更新相關(guān)信息。

這樣,每次擴(kuò)容的大小為原數(shù)組大小的約1.5倍,這個(gè)值是可以設(shè)置的,通過 `ensureCapacity()` 方法來調(diào)整。如果需要添加很多元素,建議預(yù)估需要的大小,調(diào)用 `ensureCapacity()` 來避免頻繁的擴(kuò)容操作,提高性能。

2.實(shí)現(xiàn)操作

2.1代碼截屏:

2.2效果圖:

2.3注意事項(xiàng):

 1.ArrayList  默認(rèn)長(zhǎng)度為10,當(dāng)然我們也可以設(shè)置長(zhǎng)度為其他值

例如:  ArrayList list=new  ArrayList<>(50); 當(dāng)我們打印集合長(zhǎng)度是就為:50

好處:可以減少擴(kuò)容次數(shù),提高程序在處理,運(yùn)行時(shí)的速度

2.  ArrayList 的增長(zhǎng)因子為0.5倍數(shù),擴(kuò)容倍數(shù)為1.5倍數(shù)!在進(jìn)行擴(kuò)容是數(shù)組長(zhǎng)度在有小數(shù)時(shí)會(huì)向下取整比如說:在效果圖數(shù)組長(zhǎng)度15時(shí):在添加第16個(gè)元素時(shí)擴(kuò)容后的長(zhǎng)度為:原來長(zhǎng)度*0.5+原來長(zhǎng)度(向下取整)=新長(zhǎng)度;運(yùn)用這個(gè)公式就可以得到新的擴(kuò)容數(shù)組長(zhǎng)度為22

2.4源碼:

package liuzhi_list;

import java.lang.reflect.Field;
import java.util.ArrayList;


public class demo1 {
       public static void main(String[] args)   throws  Exception{
    	   //首先創(chuàng)建一個(gè)arrayList  集合
    	   ArrayList list=new  ArrayList<>(50);
		     //通過for循環(huán)添加數(shù)據(jù)  添加100條
		     for (int i = 0; i<100; i++) {
				list.add(i);
				//打印輸出結(jié)果
			System.out.print(i+"\r");
				//發(fā)現(xiàn)集合通過for循環(huán)增加了100條數(shù)據(jù)
				System.out.println("集合有多少數(shù)據(jù):"+list.size());
				getLength(list);	
			}	     
	}         
     /**
      * 此方法通過調(diào)用arrayliat底層來操作
      * @param list
      * @throws Exception
      * @throws Exception
      */
   	private static void getLength(ArrayList list) throws Exception, Exception {
   		//通過調(diào)用 獲取 ArrayList對(duì)象類部類獲取底層的elementData字段
   		Field f = list.getClass().getDeclaredField("elementData");
   		//因?yàn)閍rraylist底層是私有化 必須通過反射 并且打開私有化權(quán)限
   		f.setAccessible(true);
   		//作用是獲取 ArrayList 對(duì)象的底層數(shù)組
   		Object[] object = (Object[]) f.get(list);
   		//打印數(shù)組長(zhǎng)度
  		System.out.println("當(dāng)前數(shù)組長(zhǎng)度: "+object.length);
   	}
}

到此這篇關(guān)于Java實(shí)現(xiàn)ArrayList自動(dòng)擴(kuò)容的文章就介紹到這了,更多相關(guān)Java ArrayList自動(dòng)擴(kuò)容內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

最新評(píng)論