為什麼ArrayList增刪效率低,及其擴容機制

2021-10-07 13:43:11 字數 2315 閱讀 9574

首先,modcount是arraylist的父類abstractlist中的變數,記錄的是關於元素的數目被修改的次數,預設值為0。

增與刪操作時, modcount一定會進行修改。改和查時modcount一定不會修改。

arraylist底層是陣列,查詢時間複雜度為 o(1) ,刪除/新增時間複雜度為 o(n)。(而鍊錶查詢時間複雜度為o(n), 刪除/新增時間複雜度為o(1))

擴容操作會導致陣列複製,批量刪除會有找出兩個集合交集的操作及陣列複製操作,因此,增、刪都相對低效。 而 改、查比較高效。

總的來說就是分兩步:

1、擴容

把原來的陣列複製到另乙個記憶體空間更大的陣列中

2、新增元素

把新元素新增到擴容以後的陣列中

1. 在無參構造中,我們看到了在用無參構造來建立物件的時候其實就是建立了乙個空陣列,長度為0

public

arraylist()

2. 在有參構造中,傳入的引數是正整數就按照傳入的引數來確定建立陣列的大小,否則異常

public

arraylist

(int initialcapacity)

else

if(initialcapacity ==0)

else

}

擴容,即 add

(e e)方法:

第一步:增加長度(關鍵點)

第二步:新增元素到陣列

如果在新增的時候原陣列是空的,就直接給乙個10的長度,否則的話就 +

1;當需要的長度大於原來陣列長度的時候就需要呼叫grow

()方法進行擴容了,相反則不需要擴容

//判斷當前arraylist是否需要進行擴容

private

void

ensureexplicitcapacity

(int mincapacity)

//arraylist擴容的核心方法,此方法用來決定擴充的容量

private

void

grow

(int mincapacity)

private

static

inthugecapacity

(int mincapacity)

// 陣列作為乙個物件,需要一定的記憶體儲存物件頭資訊,物件頭資訊最大占用記憶體不可超過8位元組。

// 2^31 -1 == 2,147,483,647。陣列需要8 bytes去儲存它自己的大小(2,147,483,647)

private

static

final

int max_array_size = integer.max_value -8;

hugecapacity

(int num)方法:

當擴容量(newcapacity)大於arraylist陣列定義的最大值後會呼叫hugecapacity來進行判斷。

如果mincapacity已經大於integer的最大值(溢位為負數)那麼丟擲outofmemoryerror(記憶體溢位)。

否則的話根據與max_array_size的比較情況確定是返回integer最大值還是max_array_size。

這邊也可以看到arraylist允許的最大容量就是integer的最大值(-2^

31~2^

31-1)。arrays.copyof 方法底層呼叫的是 system.arraycopy

public

static

void

arraycopy

(object src,

int srcpos, object dest,

int destpos,

int length)

object src: 源陣列,

int srcpos: 從源資料的起始位置開始

object dest: 目標陣列,

int destpos: 目標陣列的開始起始位置

int length: 要copy的陣列的長度

兩者區別:

arrays.

copyof

() 不僅僅只是拷貝陣列中的元素,在拷貝元素時,會建立乙個新的陣列物件

system.

arraycopy

() 只拷貝已經存在陣列元素。

vector每次擴容容量是翻倍,即為原來的2倍,而arraylist是1.5倍

ArrayList為什麼不安全

arraylist和vector安全問題 前言 執行緒安全 在多執行緒訪問的時候,採用了加鎖機制,當乙個執行緒訪問該類的某個資料時,進行保護,其他執行緒不能訪問直到該執行緒讀取完,其它執行緒才可以使用,不會出現資料不一致或資料汙染。執行緒不安全 不能提供資料保護,有可能多個執行緒先後更改資料造成所得...

linkList和arrayList增刪效能比較

最近在看資料結構,從書中所知。1.順序表在邏輯上是連續的,在物理記憶體上也是連續的。2.鍊錶在邏輯上是連續的,在物理記憶體上不一定是連續的。想起來自己專案中的 幾乎都是用的順序表list來進行增刪改查的,那麼豈不是會慢好多 還有很大的優化空間 經同事提醒決定還是先做一下資料測試再決定優不優化。下面開...

ArrayList 為什麼執行緒不安全

我們先來看看 arraylist 的 add 操作原始碼。public boolean add e e arraylist 的不安全主要體現在兩個方面。其一 elementdata size e 不是乙個原子操作,是分兩步執行的。elementdata size e size 單執行緒執行這段 完全...