JDK 普通操作 之 List 合集

2021-10-19 08:39:57 字數 4968 閱讀 9703

用的最最最最最多的list之arraylist:

先看看arraylist裡面有哪些屬性

/** 預設容量,當不傳入初始化容量時預設為10,但是不是在構造時初始化的,是在第一次新增時擴容的 */

private

static

final

int default_capacity =10;

/** 空例項的空實現(用於建構函式傳入初始化容量為0或傳入的集合長度為0) */

private

static

final object[

] empty_elementdata =

;/** 如果不傳入初始化容量預設elementdata為這個 */

private

static

final object[

] defaultcapacity_empty_elementdata =

;/** 用上面這兩個空陣列確定是有參構造還是無參構造 */

/** 陣列 */

transient object[

] elementdata;

// non-private to simplify nested class access

/** 省略 */

private

int size;

接下來看其新增操作:

整個add()方法非常簡單,ensurecapacityinternal()確定內部容量(是否需要擴容),在陣列的下乙個位置放入該元素即可

public

boolean

add(e e)

這個直接跳過,我們看其內部的兩個具體方法

private

void

ensurecapacityinternal

(int mincapacity)

計算容量:也就是看當前陣列是否初始化了,沒初始化就返回default_capacity

private

static

intcalculatecapacity

(object[

] elementdata,

int mincapacity)

return mincapacity;

}

確定是否要擴容:

判斷新增元素(size + 1)過後 是否大於 當前 陣列長度 ,大於則擴容

如果上一步是未初始化返回default_capacity,這裡的當前陣列長度就為0,也是需要擴容的

private

void

ensureexplicitcapacity

(int mincapacity)

這是真正的擴容方法,前面都只是前戲?

首先按照當前容量擴大1.5倍,看看夠不夠,不夠就取當前需要的容量

當然不能太大,最多就integer.max_value,不能再多了

複製乙個新的陣列,容量為新容量

private

void

grow

(int mincapacity)

接下來看一下另乙個add()方法:在指定index新增乙個元素

首先檢查指定的下標是否合理(是否越界或者小於0)

然後檢查是否需要擴容,和上面同理

把當前陣列的元素從index開始,都給?往後挪一位,把index這個位置騰出來給新元素

public

void

add(

int index, e element)

在看一看獲取操作:

無聊,沒意思,亂懂

public e get

(int index)

e elementdata

(int index)

最後看一眼刪除操作:

整個流程也比較簡單

public e remove

(int index)

換個姿勢的remove:

簡單來說就是遍歷陣列,待刪除元素為null就刪除元素為null的,不為null就刪除equals的元素,注意,這裡只刪除第一次出現的元素

public

boolean

remove

(object o)

}else

}return

false

;}

fastremove():和上面remove異曲同工之妙

private

void

fastremove

(int index)

下面再看經常被拿出來和arraylist比較特點的linkedlist

先看linkedlist的node

相當清晰,經典node結構

private

static

class

node

}

再看一下其內部屬性

/** size */

transient

int size =0;

/** 頭節點指標 */

transient node

first;

/** 尾節點指標 */

transient node

last;

新增操作:

擺設,缺省會新增到當前鍊錶的尾部

public

boolean

add(e e)

整個過程非常之簡單

就是新增乙個node,將新node prev指標指向尾節點,再把尾節點指向new node

如果之前尾節點為null,則把頭節點也指向當前節點,說明此時整個鍊錶就只有乙個節點

如果之前尾節點不為null,則將之前尾節點 的 next 指標指向new node

void

linklast

(e e)

另一種新增操作呢:

會判斷index是否為當前鍊錶長度,是的話就新增到最後

否則會新增到指定index處

public

void

add(

int index, e element)

node()方法:返回指定index下標處的node

首先會判斷index在鍊錶的前半部分還是後半部分,相當於二分一下

在前半部分就從前往後找,在後半部分就從後往前找

node

node

(int index)

else

}

將乙個node新增到另乙個node前面,基本操作

void

linkbefore

(e e, node

succ)

獲取方法:

和上面一樣,是有乙個二分的優化

public e get

(int index)

刪除操作:

public e remove

(int index)

將乙個節點刪除:

e unlink

(node

x)else

if(next == null)

else

x.item = null;

size--

; modcount++

;return element;

}

先看一下其屬性:

/** lock鎖實現 */

final

transient reentrantlock lock =

newreentrantlock()

;/** 內部元素陣列 */

private

transient

volatile object[

] array;

這個屬性array只能通過這兩個方法訪問和賦值,好傢伙,這是連類內部都要封裝

final object[

]getarray()

final

void

setarray

(object[

] a)

新增操作:

先加鎖,然後將當前陣列擴容1,賦值新元素給最後乙個下標處,再把當前內部陣列替換,最後解鎖

public

boolean

add(e e)

finally

}

其他新增操作和刪除操作就不過多bb了,大同小異,主要依靠reentrantlock控制當前只能有乙個執行緒進行寫操作

獲取操作:

沒有加鎖,整個獲取操作是可以多執行緒並行訪問的

因為內部陣列並無修改,只有替換,且用了volatile修飾,保證了執行緒可見性

即如果另乙個執行緒替換了內部陣列,其他執行緒會立馬知曉這個執行緒的修改,也就是獲取到的都是最新的值

public e get

(int index)

private e get

(object[

] a,

int index)

Python合集之目錄操作 一

目錄也稱為資料夾,用於分層儲存檔案。通過目錄可以分門別類地存放檔案。我們也可以通過目錄快速地找到想要的檔案。在python中,並沒有提供直接操作目錄的函式或者物件,而是需要使用內建的os和os.path模組實現。注 os模組時python內建的與作業系統功能和檔案系統相關的模組。該模組中的語句的執行...

redis 操作之List列表操作

redis list操作 reids redis 操作之list列表操作 list操作,redis中的list在在記憶體中按照乙個name對應乙個list來儲存。如圖 lpush name,values 列表新增值 在name對應的list中新增元素,每個新的元素都新增到列表的最左邊,往左新增值,也...

List去重及使用jdk8語法操作list去重

list是有序的,可以重複的。set是無序的,不可以重複的。list去重,如果t是基本型別的,只需要將list轉成set就可以去重 如果t是物件型別,那麼需要重新equals 和hashcode 方法。假如有乙個list集合 simon,kevin,lucy,kevin,lily 去掉其中重複的元素...