用的最最最最最多的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 去掉其中重複的元素...