Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ Javaにおけるスタックデータ構造 | Javaにおける高度なデータ構造
Javaデータ構造

bookJavaにおけるスタックデータ構造

メニューを表示するにはスワイプしてください

Stackは、後入れ先出し(LIFO)の原則に従うデータ構造。前述のDequeにも同じ原則が適用され、Java開発者はLIFO原則で動作する必要がある場合、Dequeの使用を推奨。Stackデータ構造は時代遅れであり、現代のJava開発では推奨されていない

ただし、推奨されなくなった、または非推奨となったコレクションも存在。

非推奨

要素が非推奨としてマークされている場合、ライブラリやプログラミング言語の作者が新しいコードでの使用を避けることを推奨し、より安全で効率的、または機能的な新しいメソッド、クラス、アプローチの採用を勧めていることを意味する。

例として、JavaVector クラスがあります。そのメソッドは、より現代的なコレクションである ArrayListLinkedList が推奨されるため、非推奨となっています。プログラマーが Vector のメソッドを使用すると、コンパイラが これらのメソッドが非推奨であるという警告を出す場合があります。

Java の例:

Main.java

Main.java

copy
12345678910111213141516
package com.example; import java.util.Vector; public class Main { public static void main(String[] args) { Vector<String> vector = new Vector<>(); // Adding an element (this method is deprecated) vector.addElement("Item"); // Compiler warning about the deprecated method // Note: 'addElement(java.lang.Object)' is deprecated. System.out.println(vector.get(0)); } }

したがって、Stack のようなデータ構造の使用は推奨されませんが、本章ではこのデータ構造について説明します。なぜなら、これは興味深いデータ構造であり、例えば Java Stack memory などで使用されているためです。

スタック

要点のみStack クラスのメソッドを見ていきます。

メソッド

push(E element): 要素をスタックの一番上に追加。

Main.java

Main.java

copy
123456789101112
package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); } }

追加は ArrayList と同様に行われるため、このメソッドと pop() メソッドを組み合わせてすぐに見てみましょう。

pop(): スタックのトップから要素を削除し、返す。

Main.java

Main.java

copy
1234567891011121314
package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); stack.pop(); System.out.println("Stack after the `pop()` method: " + stack); } }

このメソッドはスタックのトップから1つの要素を削除します。pop() メソッドはスタックから最後に追加された要素を削除することに注意してください。これがまさに LIFO 原則の動作です。

また、スタックのトップにある要素を確認することもできます。

peek(): スタックのトップにある要素を削除せずに返す

Main.java

Main.java

copy
123456789101112131415
package com.example; import java.util.Stack; public class Main { public static void main(String[] args) { Stack<String> stack = new Stack<>(); stack.push("One"); stack.push("Two"); System.out.println("Stack: " + stack); String top = stack.peek(); System.out.println("Top element of the stack: " + top); System.out.println("Stack after the `peek()` method: " + stack); } }

このメソッドでは、スタックの最上部の要素を確認します。

使用例

Stackデータ構造を使用して、ブラウザでページ間を移動する例を考えてみましょう(よく使う進む戻るの矢印ボタン)。

ブラウザ履歴の実装を計画し、2つのボタン(goBack()goForward())のメソッドを実装します。 どのボタンか分からない場合は、これらのナビゲーションボタンのことです。

これら2つのボタンを操作するメソッドを持つクラスを、Stackデータ構造を用いて実装します。

動作概要

2つのスタックと1つのString変数を使用します。1つ目のスタックは「戻る」矢印をクリックして移動したリンクを保存します。2つ目のスタックは「進む」矢印をクリックして移動したリンクを保存します。また、現在のページのリンクを保存するString変数も用意します。

このクラスには、visitPage()goBack()goForward()getCurrentPage()4つのメソッドがあります。それぞれの動作を順に説明します。

visitPage()メソッドは、パラメータで指定されたURL遷移します。新しいページに移動する際、以前のリンクはbackStackに追加されます。新しいページに移動するとforwardStackクリアされます。

コードでの実装を見てみましょう:

BrowserHistory.java

BrowserHistory.java

copy
1234567891011121314151617181920212223242526
import java.util.Stack; public class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } }

このようにして、新しいページに移動した際に前のページに戻ることができます。

次に、戻るメソッドを実装します。動作は次の通りです:現在のリンクをforwardStack追加し、その後backStackからこのリンクを削除し、currentUrl代入します。

コードでの実装を見てみましょう:

BrowserHistory.java

BrowserHistory.java

copy
12345678910
public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } }

pop() メソッドはスタックのトップから要素を削除し、その要素を返すことを思い出してください。このため、このメソッドを使用することで、URL の値を変数 currentUrl に即座に代入します。

また、backStack空でないことも確認します。そうでなければ、前のリンクに戻ることができません(単純に存在しないためです)。スタックが空の場合は、対応するメッセージを出力します。

同様にして、進むページへのナビゲーション用メソッドも実装します。スタック内の要素を単純に入れ替えます。

BrowserHistory.java

BrowserHistory.java

copy
12345678910
public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } }

残るは getCurrentPage() メソッドの実装のみであり、これは単純に currentUrl の値を返します。

テスト

次に、これらすべてを main メソッドでテストします。visitPage() メソッドを3回使用して、これらのリンクが履歴に保存されることを確認します。その後、goBack() メソッドを2回goForward() メソッドを1回使用し、記述したメソッドの機能を検証します。

この過程で、getCurrentPage() メソッドを使って状態を追跡します。以下のコードを実行し、さらに多くのリンクを挿入したり、さまざまなメソッドを使ってこのクラスの機能をテストすることもできます。

Main.java

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
package com.example; import java.util.Stack; class Main { public static void main(String[] args) { BrowserHistory browser = new BrowserHistory(); System.out.println("Default page: " + browser.getCurrentPage()); browser.visitPage("https://codefinity.com/courses/tracks/7dfbcd35-5cde-49d3-80f1-bf1096487903"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/e66c57b4-5f36-43b2-bd3b-e1398044fcab"); browser.visitPage("https://codefinity.com/courses/v2/8204075c-f832-4cb9-88b1-4e24e74ebdcb/bb00e195-715e-477d-8927-964e6e27cf16/1585fb29-47cd-47a6-9fb3-5b391cad24e0"); System.out.println("Current Page after visiting 3 pages: " + browser.getCurrentPage()); browser.goBack(); browser.goBack(); System.out.println("Current Page after going back 2 times: " + browser.getCurrentPage()); browser.goForward(); System.out.println("Current Page after going forward: " + browser.getCurrentPage()); } } class BrowserHistory { private Stack<String> backStack; private Stack<String> forwardStack; private String currentUrl; public BrowserHistory() { backStack = new Stack<>(); forwardStack = new Stack<>(); currentUrl = "https://codefinity.com/profile/my-home"; } public void visitPage(String url) { // When visiting a new page, add the current page to the "back" stack backStack.push(currentUrl); // Reset the "forward" stack as we moved to a new page forwardStack.clear(); // Set the current page to the new URL currentUrl = url; System.out.println("Visited page: " + url); } public void goBack() { if (!backStack.isEmpty()) { // Navigate to the previous page, move from the backStack to the forwardStack forwardStack.push(currentUrl); currentUrl = backStack.pop(); System.out.println("Went back to: " + currentUrl); } else { System.out.println("Cannot go back. Already at the beginning."); } } public void goForward() { if (!forwardStack.isEmpty()) { // Navigate to the next page, move from the forwardStack to the backStack backStack.push(currentUrl); currentUrl = forwardStack.pop(); System.out.println("Went forward to: " + currentUrl); } else { System.out.println("Cannot go forward. Already at the latest page."); } } public String getCurrentPage() { return currentUrl; } }

Stack クラスは非推奨であり、現代のJava開発では推奨されていません。代わりに、より効率的な代替手段である Deque の使用が推奨されます。この例では、StackLIFO原則に基づいて実装されていますが、Deque も実装可能であり、これは両端キューとしてFIFOおよびLIFOの両方の原則をサポートします。

1. Stackデータ構造の主な原則は何ですか?

2. Javaでスタックの一番上に要素を追加するために使用されるメソッドはどれですか?

3. 次のうち、Stackのより現代的な代替と考えられているJavaコレクションはどれですか?

4. Javaにおいて、pop()Stackメソッドは何を返しますか?

question mark

Stackデータ構造の主な原則は何ですか?

正しい答えを選んでください

question mark

Javaでスタックの一番上に要素を追加するために使用されるメソッドはどれですか?

正しい答えを選んでください

question mark

次のうち、Stackのより現代的な代替と考えられているJavaコレクションはどれですか?

正しい答えを選んでください

question mark

Javaにおいて、pop()Stackメソッドは何を返しますか?

正しい答えを選んでください

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 2.  4

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

セクション 2.  4
some-alt