Verwendung
Implementation siehe Fortgeschrittene Implementation mit einer Klasse, Optional
und generischem Typargument
Stack stack = new Stack<Integer>();
stack.push(10);
stack.push(5);
stack.pop(); // Some(5)
stack.pop(); // Some(10)
stack.pop(); // None
Visualisierung
Visualisierung des oberen Codebeispiels
Legende:
- Zuweisung von Variablen oder Attributen: name = Referenz
- Format von Referenzen: Typ@Arbeitsspeicheraddresse
- Wert, welcher
null
ist (Null-Referenz): Typ@0 - roter Text: Methodenaufrufe
- blaue Pfeile: Aktionen, welcher der Code ausführt
https://excalidraw.com/#json=MNAGF38noFLLYWHn1c4Fa,Dglay-iz__XIufysuBVy5w
Einfache Implementation mit int
und zwei Klassen
public class Stack {
private StackElement head;
public void push(int value) {
this.head = new StackElement(value, this.head);
}
public Integer pop() {
if (this.head == null) {
return null;
}
Integer currentHead = this.head.value;
this.head = this.head.tail;
return currentHead;
}
private static class StackElement {
public Integer value;
public StackElement tail;
public StackElement(int value, StackElement tail) {
this.value = value;
this.tail = tail;
}
}
}
Einfache Implementation mit int
und einer Klasse
package global.oskar.dsa;
public class Stack {
private Integer head;
private Stack tail;
public Stack() {
// this is only possible if head is
// an Integer, not an int
// since Integer is a class
this.head = null;
this.tail = null;
}
private Stack(int head, Stack tail) {
this.head = head;
this.tail = tail;
}
// returns null if there is no element
// on top of the stack
public Integer pop() {
if (this.head == null) {
return null;
}
if (this.tail == null) {
int currentHead = this.head;
this.head = null;
return currentHead;
}
int currentHead = this.head;
this.head = this.tail.head;
this.tail = this.tail.tail;
return currentHead;
}
public void push(int value) {
if (this.head == null) {
this.head = value;
return;
}
this.tail = new Stack(this.head, this.tail);
this.head = value;
}
}
Fortgeschrittene Implementation mit einer Klasse und einem Record, Optional
und generischem Typargument
package global.oskar.dsa;
import java.util.Optional;
public class Stack<T> {
private StackElement<T> head;
public void push(T value) {
this.head = new StackElement<>(value, this.head);
}
public Optional<T> pop() {
if (this.head == null) {
return Optional.empty();
}
T currentHead = this.head.value;
this.head = this.head.tail;
return Optional.ofNullable(currentHead);
}
private record StackElement<T>(T value, StackElement<T> tail) {
}
}
Fortgeschrittene Implementation mit einer Klasse, Optional
und generischem Typargument
package global.oskar.dsa;
import java.util.Optional;
// T is the type of the elements in the Stack
// T is set when creating the stack like:
// Stack ints = new Stack<Integer>();
// or
// Stack strings = new Stack<String>();
public class Stack<T> {
// head may be null
private T head;
private Stack<T> tail;
public Stack() {
this.head = null;
this.tail = null;
}
private Stack(T head, Stack<T> tail) {
this.head = head;
this.tail = tail;
}
// Optional is a type that represents
// either Some (a value) or None (no value)
// If there is no element on top
// then return a None, else a Some
// containing the value
public Optional<T> pop() {
if (this.head == null) {
return Optional.empty();
}
if (this.tail == null) {
final var currentHead = this.head;
this.head = null;
return Optional.of(currentHead);
}
final var currentHead = this.head;
this.head = this.tail.head;
this.tail = this.tail.tail;
return Optional.of(currentHead);
}
public void push(T value) {
if (this.head == null) {
this.head = value;
return;
}
this.tail = new Stack<>(this.head, this.tail);
this.head = value;
}
}