Skip to content

Instantly share code, notes, and snippets.

@denkspuren
Last active December 9, 2021 21:57
Show Gist options
  • Save denkspuren/4cca23cf701bcb3388258cd130899786 to your computer and use it in GitHub Desktop.
Save denkspuren/4cca23cf701bcb3388258cd130899786 to your computer and use it in GitHub Desktop.
A stack implementation without a class declaration
// 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