Skip to content

Commit 1e50706

Browse files
authored
Enhance docs, remove main, add tests in StackArray (#6019)
1 parent f3c2be2 commit 1e50706

File tree

2 files changed

+117
-32
lines changed

2 files changed

+117
-32
lines changed

src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java

+80-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
package com.thealgorithms.datastructures.stacks;
22

33
/**
4-
* This class implements a Stack using a regular array.
4+
* Implements a generic stack using an array.
5+
*
6+
* <p>This stack automatically resizes when necessary, growing to accommodate additional elements and
7+
* shrinking to conserve memory when its size significantly decreases.
8+
*
9+
* <p>Elements are pushed and popped in LIFO (last-in, first-out) order, where the last element added
10+
* is the first to be removed.
511
*
612
* @param <T> the type of elements in this stack
713
*/
@@ -13,11 +19,20 @@ public class StackArray<T> implements Stack<T> {
1319
private T[] stackArray;
1420
private int top;
1521

22+
/**
23+
* Creates a stack with a default capacity.
24+
*/
1625
@SuppressWarnings("unchecked")
1726
public StackArray() {
1827
this(DEFAULT_CAPACITY);
1928
}
2029

30+
/**
31+
* Creates a stack with a specified initial capacity.
32+
*
33+
* @param size the initial capacity of the stack, must be greater than 0
34+
* @throws IllegalArgumentException if size is less than or equal to 0
35+
*/
2136
@SuppressWarnings("unchecked")
2237
public StackArray(int size) {
2338
if (size <= 0) {
@@ -28,6 +43,11 @@ public StackArray(int size) {
2843
this.top = -1;
2944
}
3045

46+
/**
47+
* Pushes an element onto the top of the stack. Resizes the stack if it is full.
48+
*
49+
* @param value the element to push
50+
*/
3151
@Override
3252
public void push(T value) {
3353
if (isFull()) {
@@ -36,6 +56,13 @@ public void push(T value) {
3656
stackArray[++top] = value;
3757
}
3858

59+
/**
60+
* Removes and returns the element from the top of the stack. Shrinks the stack if
61+
* its size is below a quarter of its capacity, but not below the default capacity.
62+
*
63+
* @return the element removed from the top of the stack
64+
* @throws IllegalStateException if the stack is empty
65+
*/
3966
@Override
4067
public T pop() {
4168
if (isEmpty()) {
@@ -48,6 +75,12 @@ public T pop() {
4875
return value;
4976
}
5077

78+
/**
79+
* Returns the element at the top of the stack without removing it.
80+
*
81+
* @return the top element of the stack
82+
* @throws IllegalStateException if the stack is empty
83+
*/
5184
@Override
5285
public T peek() {
5386
if (isEmpty()) {
@@ -56,28 +89,72 @@ public T peek() {
5689
return stackArray[top];
5790
}
5891

92+
/**
93+
* Resizes the internal array to a new capacity.
94+
*
95+
* @param newSize the new size of the stack array
96+
*/
5997
private void resize(int newSize) {
6098
@SuppressWarnings("unchecked") T[] newArray = (T[]) new Object[newSize];
6199
System.arraycopy(stackArray, 0, newArray, 0, top + 1);
62100
stackArray = newArray;
63101
maxSize = newSize;
64102
}
65103

104+
/**
105+
* Checks if the stack is full.
106+
*
107+
* @return true if the stack is full, false otherwise
108+
*/
66109
public boolean isFull() {
67110
return top + 1 == maxSize;
68111
}
69112

113+
/**
114+
* Checks if the stack is empty.
115+
*
116+
* @return true if the stack is empty, false otherwise
117+
*/
70118
@Override
71119
public boolean isEmpty() {
72120
return top == -1;
73121
}
74122

75-
@Override public void makeEmpty() { // Doesn't delete elements in the array but if you call
76-
top = -1; // push method after calling makeEmpty it will overwrite previous values
123+
/**
124+
* Empties the stack, marking it as empty without deleting elements. Elements are
125+
* overwritten on subsequent pushes.
126+
*/
127+
@Override
128+
public void makeEmpty() {
129+
top = -1;
77130
}
78131

132+
/**
133+
* Returns the number of elements currently in the stack.
134+
*
135+
* @return the size of the stack
136+
*/
79137
@Override
80138
public int size() {
81139
return top + 1;
82140
}
141+
142+
/**
143+
* Returns a string representation of the stack.
144+
*
145+
* @return a string representation of the stack
146+
*/
147+
@Override
148+
public String toString() {
149+
StringBuilder sb = new StringBuilder();
150+
sb.append("StackArray [");
151+
for (int i = 0; i <= top; i++) {
152+
sb.append(stackArray[i]);
153+
if (i < top) {
154+
sb.append(", ");
155+
}
156+
}
157+
sb.append("]");
158+
return sb.toString();
159+
}
83160
}

src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java

+37-29
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ void testPushAndPop() {
2121
stack.push(4);
2222
stack.push(5);
2323

24-
Assertions.assertEquals(5, stack.pop()); // Stack follows LIFO, so 5 should be popped first
25-
Assertions.assertEquals(4, stack.pop()); // Next, 4 should be popped
26-
Assertions.assertEquals(3, stack.pop()); // Followed by 3
27-
Assertions.assertEquals(2, stack.pop()); // Then 2
28-
Assertions.assertEquals(1, stack.pop()); // Finally 1
24+
Assertions.assertEquals(5, stack.pop());
25+
Assertions.assertEquals(4, stack.pop());
26+
Assertions.assertEquals(3, stack.pop());
27+
Assertions.assertEquals(2, stack.pop());
28+
Assertions.assertEquals(1, stack.pop());
2929
}
3030

3131
@Test
@@ -34,34 +34,34 @@ void testPeek() {
3434
stack.push(20);
3535
stack.push(30);
3636

37-
Assertions.assertEquals(30, stack.peek()); // Peek should return 30, the top of the stack
38-
Assertions.assertEquals(3, stack.size()); // Size should remain 3 after peek
37+
Assertions.assertEquals(30, stack.peek());
38+
Assertions.assertEquals(3, stack.size());
3939

4040
stack.pop();
41-
Assertions.assertEquals(20, stack.peek()); // After popping, peek should return 20
41+
Assertions.assertEquals(20, stack.peek());
4242
}
4343

4444
@Test
4545
void testIsEmpty() {
46-
Assertions.assertTrue(stack.isEmpty()); // Initially, the stack should be empty
46+
Assertions.assertTrue(stack.isEmpty());
4747
stack.push(42);
48-
Assertions.assertFalse(stack.isEmpty()); // After pushing an element, the stack should not be empty
48+
Assertions.assertFalse(stack.isEmpty());
4949
stack.pop();
50-
Assertions.assertTrue(stack.isEmpty()); // After popping the only element, the stack should be empty again
50+
Assertions.assertTrue(stack.isEmpty());
5151
}
5252

5353
@Test
5454
void testResizeOnPush() {
55-
StackArray<Integer> smallStack = new StackArray<>(2); // Start with a small stack size
55+
StackArray<Integer> smallStack = new StackArray<>(2);
5656
smallStack.push(1);
5757
smallStack.push(2);
58-
Assertions.assertTrue(smallStack.isFull()); // Initially, the stack should be full
58+
Assertions.assertTrue(smallStack.isFull());
5959

60-
smallStack.push(3); // This push should trigger a resize
61-
Assertions.assertFalse(smallStack.isFull()); // The stack should no longer be full after resize
62-
Assertions.assertEquals(3, smallStack.size()); // Size should be 3 after pushing 3 elements
60+
smallStack.push(3);
61+
Assertions.assertFalse(smallStack.isFull());
62+
Assertions.assertEquals(3, smallStack.size());
6363

64-
Assertions.assertEquals(3, smallStack.pop()); // LIFO behavior check
64+
Assertions.assertEquals(3, smallStack.pop());
6565
Assertions.assertEquals(2, smallStack.pop());
6666
Assertions.assertEquals(1, smallStack.pop());
6767
}
@@ -74,13 +74,13 @@ void testResizeOnPop() {
7474
stack.push(3);
7575
stack.push(4);
7676

77-
stack.pop(); // Removing elements should trigger a resize when less than 1/4 of the stack is used
7877
stack.pop();
7978
stack.pop();
80-
Assertions.assertEquals(1, stack.size()); // After popping, only one element should remain
79+
stack.pop();
80+
Assertions.assertEquals(1, stack.size());
8181

8282
stack.pop();
83-
Assertions.assertTrue(stack.isEmpty()); // The stack should be empty now
83+
Assertions.assertTrue(stack.isEmpty());
8484
}
8585

8686
@Test
@@ -90,32 +90,40 @@ void testMakeEmpty() {
9090
stack.push(3);
9191
stack.makeEmpty();
9292

93-
Assertions.assertTrue(stack.isEmpty()); // The stack should be empty after calling makeEmpty
94-
Assertions.assertThrows(IllegalStateException.class, stack::pop); // Popping from empty stack should throw exception
93+
Assertions.assertTrue(stack.isEmpty());
94+
Assertions.assertThrows(IllegalStateException.class, stack::pop);
9595
}
9696

9797
@Test
9898
void testPopEmptyStackThrowsException() {
99-
Assertions.assertThrows(IllegalStateException.class, stack::pop); // Popping from an empty stack should throw an exception
99+
Assertions.assertThrows(IllegalStateException.class, stack::pop);
100100
}
101101

102102
@Test
103103
void testPeekEmptyStackThrowsException() {
104-
Assertions.assertThrows(IllegalStateException.class, stack::peek); // Peeking into an empty stack should throw an exception
104+
Assertions.assertThrows(IllegalStateException.class, stack::peek);
105105
}
106106

107107
@Test
108108
void testConstructorWithInvalidSizeThrowsException() {
109-
Assertions.assertThrows(IllegalArgumentException.class, () -> new StackArray<>(0)); // Size 0 is invalid
110-
Assertions.assertThrows(IllegalArgumentException.class, () -> new StackArray<>(-5)); // Negative size is invalid
109+
Assertions.assertThrows(IllegalArgumentException.class, () -> new StackArray<>(0));
110+
Assertions.assertThrows(IllegalArgumentException.class, () -> new StackArray<>(-5));
111111
}
112112

113113
@Test
114114
void testDefaultConstructor() {
115-
StackArray<Integer> defaultStack = new StackArray<>(); // Using default constructor
116-
Assertions.assertEquals(0, defaultStack.size()); // Initially, size should be 0
115+
StackArray<Integer> defaultStack = new StackArray<>();
116+
Assertions.assertEquals(0, defaultStack.size());
117117

118118
defaultStack.push(1);
119-
Assertions.assertEquals(1, defaultStack.size()); // After pushing, size should be 1
119+
Assertions.assertEquals(1, defaultStack.size());
120+
}
121+
122+
@Test
123+
void testToString() {
124+
stack.push(1);
125+
stack.push(2);
126+
stack.push(3);
127+
Assertions.assertEquals("StackArray [1, 2, 3]", stack.toString());
120128
}
121129
}

0 commit comments

Comments
 (0)