Stack

Die Datenstruktur “Stapel”.

java.util.Stack

java.util.Stack ist eine weitere Datenstruktur, bei der Elemente eingefügt und wieder entfernt werden können, wobei bei Stacks immer nur auf dasjenige Element zugegriffen werden kann, das zuletzt eingefügt wurde (Last-In-First-Out = LIFO). Auf Deutsch könnte man Stack als “Stapel” übersetzen.

stack1

Ein Stack kann leer sein oder kann beliebig wachsen. Mit der Methode push(E item) legt man das Element item auf den Stack, d.h. man fügt es zu oberst hinzu. pop() entfernt das oberste Element vom Stack und gibt es zurück.

stack2

Die Methode peek() gibt das Element zu oberst auf dem Stack zurück, ohne den Stack zu verändern.

Falls der Stack leer ist und man die Methode pop() oder peek() aufruft, wird die Exception EmptyStackException geworfen.

Mit der Methode search(Object o) kann man ein Element im Stack suchen, wobei die Position des Elements zurückgegeben wird. Bei den Stacks hat das oberste Element des Stacks die Position 1 und das Element darunter die Position 2, das Element darunter die Position 3, ect. Das heisst anders als bei den ArrayLists fangen wir nicht bei 0 an die Elemente zu indexieren, sondern bei 1.

Alle Methoden der Klasse java.util.Stack

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * Konstruktor: Erstellt einen leeren Stack
 */
public Stack()

/*
 * Fügt ein Element an die oberste Stelle dieses Stacks hinzu.
 */
public E push(E item)

/*
 * Entfernt das Element an der obersten Stellen und gibt dieses Element
 * als Wert dieser Funktion zurück.
 */
public E pop()

/*
 * Gibt das Element an der obersten Stelle des Stacks zurück,
 * ohne es vom Stack zu entfernen.
 */
public E peek()

/*
 * Gibt true zurück, wenn der Stack keine Elemente enthält.
 */
public boolean empty()

/*
 * Gibt die 1-basierte Position vom oberen Ende des Stapels zurück,
 * an der sich das Objekt befindet; der Rückgabewert -1 bedeutet,
 * dass sich das Objekt nicht auf dem Stapel befindet.
 */
public int search(Object o)

Beispiel

Beispiel 1

Im folgenden Beispiel erstellen wir zunächst ein leeres Stack mit Elementen vom Typ String und wenden die Methoden der Stack-Klasse an und sehen, wie diese funktionieren.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        Stack<String> colors = new Stack<>();
        colors.push("blue");
        colors.push("yellow");
        colors.push("green");
        colors.push("orange");

        System.out.println(colors); // Output: [blue, yellow, green, orange]

        System.out.println("Color on top: " + colors.peek()); // Output: Color on top: orange
        System.out.println(colors); // Output: [blue, yellow, green, orange]

        System.out.println("Color on top: " + colors.pop()); // Output: Color on top: orange
        System.out.println(colors); // Output: [blue, yellow, green]

        System.out.println("Is stack empty? " + colors.empty()); // Output: Is stack empty? false
        System.out.println("Size of stack: " + colors.size()); // Output: Size of stack: 3

        System.out.println("Position of element blue: " + colors.search("blue")); // Output: Position of element blue: 3
        System.out.println("Position of element yellow: " + colors.search("yellow")); // Output: Position of element yellow: 2
        System.out.println("Position of element green: " + colors.search("green")); // Output: Position of element green: 1

    }
}

Output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[blue, yellow, green, orange]
Color on top: orange
[blue, yellow, green, orange]
Color on top: orange
[blue, yellow, green]
Is stack empty? false
Size of stack: 3
Position of element blue: 3
Position of element yellow: 2
Position of element green: 1

Im oberen Beispiel verwenden wir die Methode size(). Diese Methode ist nicht in der java.util.Stack-Klasse implementiert, wird jedoch von der Vector-Mutterklasse geerbt. Diese Vector-Klasse implementiert zusätzlich weitere Methoden des List-Interfaces, weshalb diese auch für Stacks verwendet werden können. Ein Stack bzw. die Datenstruktur des Stacks wird jedoch durch die oben aufgeführten Methoden ausgemacht.

Beispiel 2 (EmptyStackException)

In diesem Beispiel rufen wir die pop()-Methode auf einem leeren Stack auf:

1
2
3
4
5
6
7
8
import java.util.Stack;

public class StackExampleEmptyStackExceptionA {
    public static void main(String[] args) {
        Stack<String> colors = new Stack<>();
        colors.pop(); // Throws: Exception in thread "main" java.util.EmptyStackException
    }
}

Dies führt zu folgendem Output:

1
2
3
4
5
Exception in thread "main" java.util.EmptyStackException
	at java.base/java.util.Stack.peek(Stack.java:102)
	at java.base/java.util.Stack.pop(Stack.java:84)
	at ch.puzzle.stack.StackExampleEmptyStackExceptionA.main(StackExampleEmptyStackExceptionA.java:8)

Das gleiche Verhalten lässt sich auch bei der peek()-Methode feststellen:

1
2
3
4
5
6
7
8
import java.util.Stack;

public class StackExampleEmptyStackExceptionB {
    public static void main(String[] args) {
        Stack<String> colors = new Stack<>();
        colors.peek(); // Throws: Exception in thread "main" java.util.EmptyStackException
    }
}

Wie erwartet, kriegen wir folgenden Output:

1
2
3
4
Exception in thread "main" java.util.EmptyStackException
	at java.base/java.util.Stack.peek(Stack.java:102)
	at ch.puzzle.stack.StackExampleEmptyStackExceptionB.main(StackExampleEmptyStackExceptionB.java:8)

Aufgaben

Aufgaben

Aufgaben zu Modul #J7 - Java Collections - Stack

Last modified February 3, 2023: add stack, queue + linked-list labs (dd4a5e36)