Java Stackのクイックガイド
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]にあります。