從JDK裡Stack原始碼的角度重溫棧的實現

2021-08-10 17:55:05 字數 2011 閱讀 9409

棧概念

棧是元素的集合, 其中有兩個原則操作:

- push, 它新增到集合中

- pop 則移除最近新增的元素

push - 新增元素到棧裡

下面是push,pop相關的幾個關鍵方法的原始碼

public e push(e item) 

public

synchronized

void

addelement(e obj)

private

void

ensurecapacityhelper(int mincapacity)

private

void

grow(int mincapacity)

push方法呼叫addelement(item)往棧裡新增元素,elementdata是乙個object陣列,addelement方法做的一件事就是把obj元素新增到elementdata陣列裡,陣列的長度是固定的,

不斷新增元素肯定會超陣列的容量,ensurecapacityhelper這個方法就是確認陣列的容量

是否足夠,不夠就進行擴充。接著看grow這個方法,進行擴充,oldcapacity變數記錄舊的陣列長度,newcapacity等於oldcapacity加上乙個增量,capacityincrement變數是增量,但預設為0,可以在構造器中賦值,capacityincrement為0時,增量等於oldcapacity,newcapacity相當於增加了一倍。最後呼叫arrays的copyof方法把原來的elementdata陣列複製到乙個新的陣列裡。

pop - 移除最近新增的元素

public

synchronized e pop()

public

synchronized e peek()

pop方法:移除並返回移除棧頂的元素

peek方法: 只是返回棧頂的元素

pop方法是先呼叫peek方法獲取棧頂的元素,在呼叫removeelementat方法移除。

先看peek方法, 陣列的index是從0開始,棧頂的index就是len - 1, 最終實質是返回elementdata[index]即可。

接著看removeelementat方法的實現

public

synchronized

void

removeelementat(int index)

else

if (index < 0)

int j = elementcount - index - 1;

if (j > 0)

elementcount--;

elementdata[elementcount] = null; /* to let gc do its work */

}

這個方法呼叫system.arraycopy()進行複製資料.

這個方法是native方法, 先了解一下這個方法的引數,

/**

* src : 原陣列

* srcpos : 原陣列起始位置

* dest :目標陣列

* destpos : 目標陣列起始位置

* length : 複製陣列的長度

**/public

static

native

void

arraycopy(object src, int srcpos,

object dest, int destpos,

int length);

j = 陣列長度- index(需要移除的位置) - 1;

例如有 共5個元素, 要移除c, 這裡 j 等於 c 之後的元素個數,即2個.

呼叫system.arraycopy方法時,原陣列和目標陣列都是同乙個,實質上是把d,e 複製到原來c, d 的位置上,目標陣列為

最後elementcount減1,把陣列elementdata最後乙個賦值null, 最終陣列為

JDK原始碼解析 Stack

stack是棧的實現類,棧的特點是先進後出。繼承了vector,重寫了5個方法,對vector進行了擴充套件。繼承了vector 3.1push 呼叫父類的addelement方法,新增到陣列的尾部,也就是棧頂 public e push e item 3.2 pop 出戰操作。public syn...

Stack原始碼解析 基於JDK1 8

總結public class stack extends vector stack繼承自vector,所以是執行緒安全的。public synchronized e pop public synchronized e peek public e push e item public synchron...

學習JDK1 8集合原始碼之 Stack

stack是集合中對資料結構棧的一種實現,棧的原則是先進先後出,與佇列相反 先進先出 stack是繼承自vector的,意味著它也是由陣列實現的執行緒安全的,不考慮執行緒安全的情況下完全可以用linkedlist當做棧來使用。stack的實現很簡單,核心引數和方法都繼承自vector,因為它可以呼叫...