diff --git a/clients/src/main/java/com/hithomelabs/clients/ArrayStackClient.java b/clients/src/main/java/com/hithomelabs/clients/ArrayStackClient.java new file mode 100644 index 0000000..53a40c1 --- /dev/null +++ b/clients/src/main/java/com/hithomelabs/clients/ArrayStackClient.java @@ -0,0 +1,19 @@ +package com.hithomelabs.clients; + +import com.hithomelabs.princeton1.module4.ArrayStack; +import com.hithomelabs.princeton1.module4.Stack; + +public class ArrayStackClient { + public static void main(String[] args) { + Stack stack = new ArrayStack(); + for(int i = 0; i < 21; i++){ + stack.push(i); + } + // Using object s, as stack is generic but every java Object has implementation of toString() + for (Object s : stack) + System.out.println(s); + while(!stack.isEmpty()){ + System.out.println(stack.pop()); + } + } +} diff --git a/clients/src/main/java/com/hithomelabs/clients/Main.java b/clients/src/main/java/com/hithomelabs/clients/LinkedArrayClient.java similarity index 95% rename from clients/src/main/java/com/hithomelabs/clients/Main.java rename to clients/src/main/java/com/hithomelabs/clients/LinkedArrayClient.java index d8c5d68..ce51e32 100644 --- a/clients/src/main/java/com/hithomelabs/clients/Main.java +++ b/clients/src/main/java/com/hithomelabs/clients/LinkedArrayClient.java @@ -4,7 +4,7 @@ package com.hithomelabs.clients; import com.hithomelabs.princeton1.module4.LinkedStack; import com.hithomelabs.princeton1.module4.Stack; -public class Main { +public class LinkedArrayClient { public static void main(String[] args) { Stack stack = new LinkedStack(); stack.push("hello"); diff --git a/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayStack.java b/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayStack.java new file mode 100644 index 0000000..42e0623 --- /dev/null +++ b/module4/src/main/java/com/hithomelabs/princeton1/module4/ArrayStack.java @@ -0,0 +1,96 @@ +package com.hithomelabs.princeton1.module4; +import java.util.Iterator; + +// Concrete implementation of stack using arrays +// Creating a generic stack of type E +public class ArrayStack extends Stack { + + // Capacity and size are two variables, capacity determines total capacity of array, capacity defaults at 10 + // Everytime size == capacity, capacity = 2 * capacity + private static final int DEFAULT_CAPACITY = 10; + private int capacity; + private int size; + private E[] arr; + + public ArrayStack(int capacity){ + this.capacity = capacity; + this.arr = (E[]) new Object[this.capacity]; + } + + // Constructor chaining, default constructor will call parametrised constructor with default initial capacity 10 + public ArrayStack(){ + this(DEFAULT_CAPACITY); + } + + @Override + public boolean isEmpty() { + return this.size == 0; + } + + private void changeCapacity(int newCapacity){ + E[] resizedArr = (E[]) new Object[newCapacity]; + for (int i = 0; i < this.size; i++) + resizedArr[i] = this.arr[i]; + this.arr = resizedArr; + } + + private void incrementSize(){ + if (this.size == this.capacity){ + this.capacity = 2 * this.capacity; + changeCapacity(this.capacity); + } + } + + // Push always happens at the end of the stack + // Say the size of the stack is 1, new element gets inserted at 1 + @Override + public void push(E element) { + // Lazy approach, we assume size to always be lesser than capacity + this.incrementSize(); + this.arr[this.size++] = element; + } + + @Override + public E pop() { + if (isEmpty()) + return null; + else{ + E e = this.arr[--this.size]; + this.arr[this.size] = null; + this.checkResize(); + return e; + } + } + + private void checkResize() { + if (this.size < this.capacity / 4 && this.capacity > 10){ + this.capacity = this.capacity / 2; + changeCapacity(this.capacity); + } + } + + @Override + public int size() { + return this.size; + } + + @Override + public Iterator iterator() { + return new Iterator() { + + int current = 0; + + @Override + public boolean hasNext() { + return current != size; + } + + @Override + public E next() { + E element = arr[current]; + current = current + 1; + return element; + } + }; + } +}