更新時(shí)間:2022-04-02 11:19:59 來源:動力節(jié)點(diǎn) 瀏覽1958次
在這篇快速文章中,我們將介紹java.util.Stack類并開始研究如何使用它。
堆棧是一種通用數(shù)據(jù)結(jié)構(gòu),它表示允許在恒定時(shí)間內(nèi)推送/彈出元素的對象的 LIFO(后進(jìn)先出)集合。
對于新的實(shí)現(xiàn),我們應(yīng)該支持Deque接口及其實(shí)現(xiàn)。 雙端隊(duì)列 定義了一組更完整和一致的 LIFO 操作。但是,我們可能仍然需要處理 Stack類,尤其是在遺留代碼中,所以理解它很重要。
讓我們首先使用默認(rèn)的無參數(shù)構(gòu)造函數(shù)創(chuàng)建一個(gè)空的Stack實(shí)例:
@Test
public void whenStackIsCreated_thenItHasSizeZero() {
Stack<Integer> intStack = new Stack<>();
assertEquals(0, intStack.size());
}
這將創(chuàng)建一個(gè)默認(rèn)容量為 10的Stack 。如果添加的元素?cái)?shù)量超過Stack總大小,它將自動加倍。但是,它的大小在刪除元素后永遠(yuǎn)不會縮小。
Stack是Vector的直接子類;這意味著與它的超類類似,它是一個(gè)同步的實(shí)現(xiàn)。
但是,并不總是需要同步,在這種情況下,建議使用ArrayDeque。
讓我們首先使用push()方法將一個(gè)元素添加到Stack的頂部- 該方法還返回添加的元素:
@Test
public void whenElementIsPushed_thenStackSizeIsIncreased() {
Stack<Integer> intStack = new Stack<>();
intStack.push(1);
assertEquals(1, intStack.size());
}
使用push()方法與使用addElement()的效果相同。唯一的區(qū)別是addElement ()返回操作的結(jié)果,而不是添加的元素。
我們還可以一次添加多個(gè)元素:
@Test
public void whenMultipleElementsArePushed_thenStackSizeIsIncreased() {
Stack<Integer> intStack = new Stack<>();
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
boolean result = intStack.addAll(intList);
assertTrue(result);
assertEquals(7, intList.size());
}
接下來,讓我們看看如何獲??取和刪除Stack中的最后一個(gè)元素:
@Test
public void whenElementIsPoppedFromStack_thenElementIsRemovedAndSizeChanges() {
Stack<Integer> intStack = new Stack<>();
intStack.push(5);
Integer element = intStack.pop();
assertEquals(Integer.valueOf(5), element);
assertTrue(intStack.isEmpty());
}
我們也可以在不移除S大頭釘?shù)那闆r下獲得最后一個(gè)元素:
@Test
public void whenElementIsPeeked_thenElementIsNotRemovedAndSizeDoesNotChange() {
Stack<Integer> intStack = new Stack<>();
intStack.push(5);
Integer element = intStack.peek();
assertEquals(Integer.valueOf(5), element);
assertEquals(1, intStack.search(5));
assertEquals(1, intStack.size());
}
(1)搜索
Stack允許我們搜索一個(gè)元素 并獲取它與頂部的距離:
@Test
public void whenElementIsOnStack_thenSearchReturnsItsDistanceFromTheTop() {
Stack<Integer> intStack = new Stack<>();
intStack.push(5);
intStack.push(8);
assertEquals(2, intStack.search(5));
}
結(jié)果是給定對象的索引。如果存在多個(gè)元素,則返回最接近頂部的元素的索引 。位于堆棧頂部的項(xiàng)目被視為位于位置 1。
如果找不到對象,search()將返回 -1。
(2)獲取元素索引
要獲取 S大頭釘上元素的索引,我們還可以使用indexOf()和lastIndexOf()方法:
@Test
public void whenElementIsOnStack_thenIndexOfReturnsItsIndex() {
Stack<Integer> intStack = new Stack<>();
intStack.push(5);
int indexOf = intStack.indexOf(5);
assertEquals(0, indexOf);
}
lastIndexOf()將始終找到最接近堆棧頂部的元素的索引。這與search()的工作方式非常相似——重要的區(qū)別是它返回索引,而不是與頂部的距離:
@Test
public void whenMultipleElementsAreOnStack_thenIndexOfReturnsLastElementIndex() {
Stack<Integer> intStack = new Stack<>();
intStack.push(5);
intStack.push(5);
intStack.push(5);
int lastIndexOf = intStack.lastIndexOf(5);
assertEquals(2, lastIndexOf);
}
除了用于刪除和檢索元素的pop()操作之外,我們還可以使用從Vector類繼承的多個(gè)操作來刪除元素。
(1)刪除指定元素
我們可以使用removeElement()方法刪除給定元素的第一次出現(xiàn):
@Test
public void whenRemoveElementIsInvoked_thenElementIsRemoved() {
Stack<Integer> intStack = new Stack<>();
intStack.push(5);
intStack.push(5);
intStack.removeElement(5);
assertEquals(1, intStack.size());
}
我們還可以使用removeElementAt()來刪除Stack中指定索引下的元素:
@Test
public void whenRemoveElementAtIsInvoked_thenElementIsRemoved() {
Stack<Integer> intStack = new Stack<>();
intStack.push(5);
intStack.push(7);
intStack.removeElementAt(1);
assertEquals(-1, intStack.search(7));
}
(2)刪除多個(gè)元素
讓我們快速看一下如何使用removeAll() API 從Stack中刪除多個(gè)元素——它將Collection作為參數(shù)并從Stack中刪除所有匹配的元素:
@Test
public void givenElementsOnStack_whenRemoveAllIsInvoked_thenAllElementsFromCollectionAreRemoved() {
Stack<Integer> intStack = new Stack<>();
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
intStack.addAll(intList);
intStack.add(500);
intStack.removeAll(intList);
assertEquals(1, intStack.size());
assertEquals(1, intStack.search(500));
}
也可以使用clear()或removeAllElements()方法從堆棧中刪除所有元素;這兩種方法的工作原理相同:
@Test
public void whenRemoveAllElementsIsInvoked_thenAllElementsAreRemoved() {
Stack<Integer> intStack = new Stack<>();
intStack.push(5);
intStack.push(7);
intStack.removeAllElements();
assertTrue(intStack.isEmpty());
}
(3)使用過濾器刪除元素
我們還可以使用條件從堆棧中刪除元素。讓我們看看如何使用removeIf ()執(zhí)行此操作,并使用過濾器表達(dá)式作為參數(shù):
@Test
public void whenRemoveIfIsInvoked_thenAllElementsSatysfyingConditionAreRemoved() {
Stack<Integer> intStack = new Stack<>();
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
intStack.addAll(intList);
intStack.removeIf(element -> element < 6);
assertEquals(2, intStack.size());
}
Stack允許我們同時(shí)使用Iterator和ListIterator。主要區(qū)別在于第一個(gè)允許我們在一個(gè)方向上遍歷Stack,第二個(gè)允許我們在兩個(gè)方向上執(zhí)行此操作:
@Test
public void whenAnotherStackCreatedWhileTraversingStack_thenStacksAreEqual() {
Stack<Integer> intStack = new Stack<>();
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
intStack.addAll(intList);
ListIterator<Integer> it = intStack.listIterator();
Stack<Integer> result = new Stack<>();
while(it.hasNext()) {
result.push(it.next());
}
assertThat(result, equalTo(intStack));
}
Stack返回的所有迭代器都是快速失敗的。
Stack是一個(gè)集合,這意味著我們可以將它與 Java 8 Streams API 一起使用。將Stream與Stack一起使用類似于將其與任何其他Collection集合一起使用:
@Test
public void whenStackIsFiltered_allElementsNotSatisfyingFilterConditionAreDiscarded() {
Stack<Integer> intStack = new Stack<>();
List<Integer> inputIntList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 9, 10);
intStack.addAll(inputIntList);
List<Integer> filtered = intStack
.stream()
.filter(element -> element <= 3)
.collect(Collectors.toList());
assertEquals(3, filtered.size());
}
相關(guān)閱讀
初級 202925
初級 203221
初級 202629
初級 203743