【Java】java.util.Stackの構造と使い方

当ページのリンクには広告が含まれています。
目次

Stackとは?

定義

オブジェクトの後入れ先出し(LIFO)スタックを表します。これは、ベクトルをスタックとして処理する5つのオペレーションでVectorクラスを拡張します。

通常のpushオペレーションとpopオペレーションが提供されるほか、スタックの先頭の項目でpeek
を行うメソッド、スタックがemptyかどうかを判定するメソッド、スタックから項目をsearchし、先頭から何番目かを見つけるメソッドが提供されています。

引用元)https://docs.oracle.com/javase/jp/8/docs/api/java/util/Stack.html

ポイントは後入れ先出しの構造を持っていることです。

後入れ先出しとは、最後に入れたものから取り出す仕組みです。

構造

箱の中にどんどん上積みしていくイメージです。上積みしているので、取り出すときは最後に入れたものから取り出すことになります。

入り口と出口が同じと考えると簡単です。

Push(追加)

Pop(取り出し)

StackよりDequeが推奨

Java6で実装されたDequeがStackよりも推奨されていますので、新しく実装する場合、または置き換え可能な場合はDequeを実装してください。

両端キューは、LIFO (後入れ先出し)スタックとして使用することもできます。.従来のStackクラスよりもこのインタフェースを優先して使用してください。

引用元)https://docs.oracle.com/javase/jp/8/docs/api/java/util/Deque.html

使い方

エンジニア, パソコン, ノマド

追加

ジェネリクスで型を指定して、その型のオブジェクトをpushメソッドで追加します。

取り出し

追加されたオブジェクトはpopメソッドで取り出せます。

空の状態でpopするとEmptyStackExceptionがスローされます。

検索

一番上(最後)に追加された位置からの番号を取得します。開始は1からです。

存在しない場合は、-1 が取得されます。

確認

peekメソッドを使います。

一番上(最後)に追加されたオブジェクトをスタックから取り出すことなく取得できるため、実行後に削除されません。

スタックが空の時に呼ばれると、EmptyStackException がスローされます。

要素が空か

emptyメソッドを使います。戻り値はbooleanです。

どういう時に使うのか?

LIFO(後入れ先出し)の仕組みが応用できるケースで使われます。

ブラウザの操作履歴の管理

「戻る」「進む」操作を実装する際に操作履歴として利用できます。

ブラウザの基本的な履歴管理を再現すると以下のような実装例になります。

実装例

実行結果

Visited: Page1
Visited: Page2
Visited: Page3
Back to: Page2
Back to: Page1
Forward to: Page2
Visited: Page4
Back to: Page2
Forward to: Page4
Current Page: Page4

動作の説明

  1. visit(String url):
    • 新しいページを開くと、現在のページが「戻る履歴」に追加され、進む履歴をクリアする。
  2. back():
    • 「戻る履歴」から1ページ取得して、現在のページを「進む履歴」に追加する。
  3. forward():
    • 「進む履歴」から1ページ取得して、現在のページを「戻る履歴」に追加する。
  4. current():
    • 現在のページを表示します。

JSONなどの括弧の整合性チェック

括弧のバランスチェック(例: {[()]} が正しいかを判定)などにも使えます。

以下はパラメータとして渡される括弧をスタックで管理し、逆順に処理して括弧がペアになっているかをチェックする実装例です。

実装例

実行結果

Input: {[()]} -> Balanced
Input: {[(])} -> Not Balanced
Input: ((())) -> Balanced
Input: [{()}]() -> Balanced
Input: {[} -> Not Balanced
Input: ((()) -> Not Balanced
Input: -> Balanced

動作の説明

  1. isBalanced(String input)
    • 文字列を1文字ずつチェック。
    • 開き括弧はスタックにプッシュ。
    • 閉じ括弧の場合、スタックのトップと比較して対応するペアがあるか確認。
  2. isMatchingPair(char open, char close)
    • 開き括弧と閉じ括弧が対応するペアかどうかを判定。
  3. テストケース
    • 括弧が対応しているものは Balanced
    • 括弧のペアが不正なものは Not Balanced
    • 空文字列 "" は括弧がないため Balanced と見なす。

まとめ

  • StackはLIFO(後入れ先出し)の構造をしており、最後に入れたものから取得する。
  • Java6からはDequeが推奨になっている。
  • 使い方はシンプルにLIFOの操作性と用語を理解していればOK。
  • Stackを使うと実装が楽になる場合は利用しよう。

最後までお読み頂き、ありがとうございました!
ご意見・ご要望がありましたら、遠慮なくコメント下さい!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

リーマンショックの影響で26歳の時にIT業界から離れ、紆余曲折を経て34歳でエンジニアに復帰。
現在はフリーランスエンジニア兼コアファクトリ合同会社代表。
得意な言語はJava。

新人教育経験あり(わからなくて進まない子を放置しない方針)
Javaの新人教育にお困りでしたらお声がけください。

■保有資格
・Java Gold SE 11

コメント

コメントする

CAPTCHA


目次