Last active
December 9, 2021 21:57
-
-
Save denkspuren/4cca23cf701bcb3388258cd130899786 to your computer and use it in GitHub Desktop.
A stack implementation without a class declaration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a stack implementation without a class declaration | |
interface Stackable<T> { | |
static <U> Stackable<U> emptyStack() { | |
return new Stackable<U>(){}; | |
} | |
private static <U> Stackable<U> instantiate(Stackable<U> underneath, U item) { | |
return new Stackable<U>() { | |
public boolean isEmpty() { return false; } | |
public Stackable<U> pop() { return underneath; } | |
public U top() { return item; } | |
}; | |
} | |
default boolean isEmpty() { return true; } | |
default Stackable<T> push(T item) { return Stackable.<T>instantiate(this, item); }; | |
default Stackable<T> pop() { throw new UnsupportedOperationException(); } | |
default T top() { throw new UnsupportedOperationException(); } | |
} | |
// Testing -- Hint: This code is for execution in the jshell | |
AssertionError ae; | |
try { assert false; } | |
catch (AssertionError exception) { ae = exception; } | |
if (ae == null) System.out.println("WARNING: For testing call \"jshell -R-ea\""); | |
assert Stackable.<Integer>emptyStack().isEmpty(); | |
assert !Stackable.<Integer>emptyStack().push(4).isEmpty(); | |
assert !Stackable.<Integer>emptyStack().push(4).push(5).isEmpty(); | |
assert Stackable.<Integer>emptyStack().push(4).pop().isEmpty(); | |
assert Stackable.<Integer>emptyStack().push(4).push(5).pop().pop().isEmpty(); | |
assert Stackable.<Integer>emptyStack().push(4).push(5).top() == 5; | |
assert Stackable.<Integer>emptyStack().push(4).push(5).pop().top() == 4; | |
Stackable<Integer> stack = Stackable.emptyStack(); | |
assert stack == stack.push(4).pop(); | |
assert stack == stack.push(4).push(5).pop().pop(); | |
try { stack.top(); } catch (UnsupportedOperationException e) { } | |
try { stack.pop(); } catch (UnsupportedOperationException e) { } | |
/* DEMO | |
jshell> Stackable.<Integer>emptyStack() | |
$17 ==> Stackable$1@312b1dae | |
jshell> $17.isEmpty() | |
$18 ==> true | |
jshell> $17.top() | |
| Exception java.lang.UnsupportedOperationException | |
| at Stackable.top (#1:15) | |
| at (#19:1) | |
jshell> $17.push(4) | |
$20 ==> Stackable$2@15327b79 | |
jshell> $20.isEmpty() | |
$23 ==> false | |
jshell> $20.top() | |
$24 ==> 4 | |
jshell> $20.pop() | |
$25 ==> Stackable$1@312b1dae | |
*/ | |
// NEXT: Let's define a state based stack interface | |
// and use the above interface for implementation purposes | |
// Again, no class declaration is needed! | |
interface Stacking<T> { | |
static <U> Stacking<U> instantiate() { | |
return new Stacking<U>() { | |
Stackable<U> instance = Stackable.<U>emptyStack(); | |
public boolean isEmpty() { return instance.isEmpty(); } | |
public void push(U item) { instance = instance.<U>push(item); } | |
public void pop() { instance = instance.pop(); } | |
public U top() { return instance.top(); } | |
}; | |
} | |
boolean isEmpty() ; | |
void push(T item) ; | |
void pop() ; | |
T top() ; | |
} | |
// Testing | |
Stacking<Integer> stack = Stacking.<Integer>instantiate(); | |
assert stack.isEmpty(); | |
stack.push(5); | |
assert !stack.isEmpty(); | |
assert stack.top() == 5; | |
stack.push(7); | |
assert !stack.isEmpty(); | |
assert stack.top() == 7; | |
stack.pop(); | |
assert !stack.isEmpty(); | |
assert stack.top() == 5; | |
stack.pop(); | |
assert stack.isEmpty(); | |
try { stack.top(); } catch (UnsupportedOperationException e) { } | |
try { stack.pop(); } catch (UnsupportedOperationException e) { } | |
/* DEMO | |
jshell> Stacking.<Integer>instantiate() | |
$35 ==> Stacking$1@cc34f4d | |
jshell> $35.isEmpty() | |
$36 ==> true | |
jshell> $35.push(5) | |
jshell> $35.isEmpty() | |
$38 ==> false | |
jshell> $35.push(7) | |
jshell> $35 | |
$35 ==> Stacking$1@cc34f4d | |
jshell> $35.isEmpty() | |
$41 ==> false | |
jshell> $35.top() | |
$42 ==> 7 | |
jshell> $35.pop() | |
jshell> $35.top() | |
$44 ==> 5 | |
jshell> $35.isEmpty() | |
$45 ==> false | |
jshell> $35.pop() | |
jshell> $35.isEmpty() | |
$48 ==> true | |
jshell> $35.top() | |
| Exception java.lang.UnsupportedOperationException | |
| at Stackable.top (#33:15) | |
| at Stacking$1.top (#34:8) | |
| at (#49:1) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment