diff --git a/core-java-modules/core-java-collections-4/pom.xml b/core-java-modules/core-java-collections-4/pom.xml
index 0e3cabf40e..b4f8aa6320 100644
--- a/core-java-modules/core-java-collections-4/pom.xml
+++ b/core-java-modules/core-java-collections-4/pom.xml
@@ -25,7 +25,7 @@
- 3.18.0
+ 3.19.0
diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/ArrayLifoStack.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/ArrayLifoStack.java
new file mode 100644
index 0000000000..16fdec5b77
--- /dev/null
+++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/ArrayLifoStack.java
@@ -0,0 +1,91 @@
+package com.baeldung.collections.dequestack;
+
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+
+public class ArrayLifoStack implements LifoStack {
+ private final Deque deque = new ArrayDeque<>();
+
+ @Override
+ public void push(E item) {
+ deque.addFirst(item);
+ }
+
+ @Override
+ public E pop() {
+ return deque.removeFirst();
+ }
+
+ @Override
+ public E peek() {
+ return deque.peekFirst();
+ }
+
+ // implementing methods from the Collection interface
+ @Override
+ public int size() {
+ return deque.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return deque.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return deque.contains(o);
+ }
+
+ @Override
+ public Iterator iterator() {
+ return deque.iterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return deque.toArray();
+ }
+
+ @Override
+ public T[] toArray(T[] a) {
+ return deque.toArray(a);
+ }
+
+ @Override
+ public boolean add(E e) {
+ return deque.add(e);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return deque.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection> c) {
+ return deque.containsAll(c);
+ }
+
+ @Override
+ public boolean addAll(Collection extends E> c) {
+ return deque.addAll(c);
+ }
+
+ @Override
+ public boolean removeAll(Collection> c) {
+ return deque.removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(Collection> c) {
+ return deque.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ deque.clear();
+ }
+}
diff --git a/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/LifoStack.java b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/LifoStack.java
new file mode 100644
index 0000000000..11e07e3555
--- /dev/null
+++ b/core-java-modules/core-java-collections-4/src/main/java/com/baeldung/collections/dequestack/LifoStack.java
@@ -0,0 +1,12 @@
+package com.baeldung.collections.dequestack;
+
+import java.util.Collection;
+
+public interface LifoStack extends Collection {
+
+ E peek();
+
+ E pop();
+
+ void push(E item);
+}
\ No newline at end of file
diff --git a/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/dequestack/StackVsDequeUnitTest.java b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/dequestack/StackVsDequeUnitTest.java
new file mode 100644
index 0000000000..ca3b0e8d54
--- /dev/null
+++ b/core-java-modules/core-java-collections-4/src/test/java/com/baeldung/collections/dequestack/StackVsDequeUnitTest.java
@@ -0,0 +1,90 @@
+package com.baeldung.collections.dequestack;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.Stack;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class StackVsDequeUnitTest {
+
+ @Test
+ void givenAStack_whenAccessByIndex_thenElementCanBeRead() {
+ Stack myStack = new Stack<>();
+ myStack.push("I am the 1st element."); //index 0
+ myStack.push("I am the 2nd element."); //index 1
+ myStack.push("I am the 3rd element."); //index 2
+ //access by index
+ assertThat(myStack.get(0)).isEqualTo("I am the 1st element.");
+ }
+
+ @Test
+ void givenAStack_whenIterate_thenFromBottomToTop() {
+ Stack myStack = new Stack<>();
+ myStack.push("I am at the bottom.");
+ myStack.push("I am in the middle.");
+ myStack.push("I am at the top.");
+
+ Iterator it = myStack.iterator();
+
+ assertThat(it).toIterable().containsExactly(
+ "I am at the bottom.",
+ "I am in the middle.",
+ "I am at the top.");
+ }
+
+ @Test
+ void givenAStack_whenAddOrRemoveByIndex_thenElementCanBeAddedOrRemoved() {
+ Stack myStack = new Stack<>();
+ myStack.push("I am the 1st element.");
+ myStack.push("I am the 3rd element.");
+
+ assertThat(myStack.size()).isEqualTo(2);
+
+ //insert by index
+ myStack.add(1, "I am the 2nd element.");
+ assertThat(myStack.size()).isEqualTo(3);
+ assertThat(myStack.get(1)).isEqualTo("I am the 2nd element.");
+ //remove by index
+ myStack.remove(1);
+ assertThat(myStack.size()).isEqualTo(2);
+ }
+
+ @Test
+ void givenADeque_whenAddOrRemoveLastElement_thenTheLastElementCanBeAddedOrRemoved() {
+ Deque myStack = new ArrayDeque<>();
+ myStack.push("I am the 1st element.");
+ myStack.push("I am the 2nd element.");
+ myStack.push("I am the 3rd element.");
+
+ assertThat(myStack.size()).isEqualTo(3);
+
+ //insert element to the bottom of the stack
+ myStack.addLast("I am the NEW element.");
+ assertThat(myStack.size()).isEqualTo(4);
+ assertThat(myStack.peek()).isEqualTo("I am the 3rd element.");
+
+ //remove element from the bottom of the stack
+ String removedStr = myStack.removeLast();
+ assertThat(myStack.size()).isEqualTo(3);
+ assertThat(removedStr).isEqualTo("I am the NEW element.");
+ }
+
+ @Test
+ void givenADeque_whenIterate_thenFromTopToBottom() {
+ Deque myStack = new ArrayDeque<>();
+ myStack.push("I am at the bottom.");
+ myStack.push("I am in the middle.");
+ myStack.push("I am at the top.");
+
+ Iterator it = myStack.iterator();
+
+ assertThat(it).toIterable().containsExactly(
+ "I am at the top.",
+ "I am in the middle.",
+ "I am at the bottom.");
+ }
+}
\ No newline at end of file