1概要

この記事では、

java.util.Stack

クラスを紹介し、それをどのように利用できるかを見ていきます。

__


Stack

は、オブジェクトのLIFO(後入れ先出し)コレクションを表す一般的なデータ構造で、要素を一定時間内にプッシュ/ポップすることができます。


2作成

デフォルトの引数なしのコンストラクタを使用して、

Stack

の空のインスタンスを作成することから始めましょう。

@Test
public void whenStackIsCreated__thenItHasSize0() {
    Stack<Integer> intStack = new Stack();

    assertEquals(0, intStack.size());
}

これは

デフォルトの容量10の

Stack

を作成します。

追加された要素の数がTotal

Stack

のサイズを超えると、自動的に2倍になります。ただし、要素を削除した後にそのサイズが縮小することはありません。


3同期


Stack



Vector

の直接のサブクラスです。これは、そのスーパークラスと同じように、


synchronized


実装であることを意味します。

ただし、同期は必ずしも必要ではありません。そのような場合は、

ArrayDeque

を使用することをお勧めします。


4追加中


push()

メソッドを使用して、

Stack

の先頭に要素を追加することから始めましょう – 追加された要素も返されます。

@Test
public void whenElementIsPushed__thenStackSizeIsIncreased() {
    Stack<Integer> intStack = new Stack();
    intStack.push(1);

    assertEquals(1, intStack.size());
}


push()

メソッドを使用すると、____addElement()を使用するのと同じ効果があります。

  • T


    __



    唯一の違いは、addElement()__が追加された要素の代わりに操作の結果を返すことです。

    **

一度に複数の要素を追加することもできます。

@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());
}


5取得中

次に、

Stack

の最後の要素を取得して削除する方法を見てみましょう。

@Test
public void whenElementIsPoppedFromStack__thenSizeChanges() {
    Stack<Integer> intStack = new Stack();
    intStack.push(5);
    intStack.pop();

    assertTrue(intStack.isEmpty());
}

削除せずにS

__tack

__の最後の要素を取得することもできます。

@Test
public void whenElementIsPeeked__thenElementIsNotRemoved() {
    Stack<Integer> intStack = new Stack();
    intStack.push(5);
    intStack.peek();

    assertEquals(1, intStack.search(5));
    assertEquals(1, intStack.size());
}


6. 要素を検索する


6.1. サーチ


Stack

を使用すると、要素____を検索して上からの距離を取得できます。

@Test
public void whenElementIsOnStack__thenSearchReturnsItsDistanceFromTheTop() {
    Stack<Integer> intStack = new Stack();
    intStack.push(5);

    assertEquals(1, intStack.search(5));
}

結果は与えられた

Object

のインデックスです。複数の

Object

が存在する場合は、一番上の

Object

のインデックスが返されます。スタックの一番上にある項目は、位置1にあると見なされます。


Object

が見つからない場合、

search()

は-1を返します。


6.2. 要素のインデックスを取得する

S

tackの要素のインデックスを取得するには、

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()

と非常によく似た働きをします – 重要な違いは

上からの距離ではなく

インデックスを返すことです** :

@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);
}


7. 要素を削除する

要素の削除と取得の両方に使用される

pop()

操作とは別に、

Vector

クラス____から継承した複数の操作を使用して要素を削除することもできます。


7.1. 指定した要素を削除する


removeElement()

メソッドを使用して、特定の要素の最初の出現を削除できます。

@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));
}


7.2. 複数の要素を削除する


removeAll()

APIを使用して

Stack

から複数の要素を削除する方法を簡単に見てみましょう。これは

Collection

を引数として使用し、一致するすべての要素を

Stack

から削除します。

@Test
public void 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());
}


clear()

または

removeAllElements()

メソッドを使用して

Stack

からすべての要素を削除することもできます。これらの方法はどちらも同じように機能します。

@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());
}


7.3. フィルタを使用した要素の削除


Stackから要素を削除するための条件を使用することもできます。フィルタ式を引数として、

removeIf()__を使用してこれを実行する方法を見てみましょう。

@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());
}


8繰り返し


Stack

を使用すると、

Iterator



ListIteratorの両方を使用できます。主な違いは、1つ目は

Stack__を一方向にトラバースできること、2つ目は両方向にこれを行えることです。

@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

によって返されるすべての

Iterators

は、フェイルファストです。


9ストリームAPI


A Stack

はコレクションです。つまり、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);
    int[]intArray = intStack.stream()
      .mapToInt(element -> (int)element)
      .filter(element -> element <= 3)
      .toArray();

    assertEquals(3, intArray.length);
}


10概要

このチュートリアルは、Java

Stack

を理解するためのクイックガイドです。このトピックについて詳しくは、https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html[Javadoc]を参照してください。

そして、いつものように、すべてのコードサンプルはhttps://github.com/eugenp/tutorials/tree/master/core-java[over on Github]にあります。