In: Computer Science
Task Generics: GenericStack Class. Java.
package Modul02;
public class GenericStack<E> {
private java.util.ArrayList<E> list = new java.util.ArrayList<>();
public int size() {
return list.size();
}
public E peek() {
return list.get(size() - 1);
}
public void push(E o) {
list.add(o);
}
public E pop() {
E o = list.get(size() - 1);
list.remove(size() - 1);
return o;
}
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public String toString() {
return "stack: " + list.toString();
}
}
package Modul02;
public class TestGenericStack {
public static void main(String[] args) {
GenericStack<String> gsString = new GenericStack<>();
gsString.push("one");
gsString.push("two");
gsString.push("three");
while (!(gsString.isEmpty())) {
System.out.println(gsString.pop());
}
GenericStack<Integer> gsInteger = new GenericStack<>();
gsInteger.push(1);
gsInteger.push(2);
gsInteger.push(3);
//gsInteger.push("4");
while (!(gsInteger.isEmpty())) {
System.out.println(gsInteger.pop());
}
}
}
Create a new version of GenericStack that uses an array instead of an ArrayList (this version should also be generic). Be sure to check the size of the array before adding a new item; - if the array becomes full, double the size of the array, and you must copy elements from the old array to the new one.
Note that one cannot use the new operator on a generic type, new E is not allowed.
To create the generic array, a cast must:
private E [] elements = (E[]) new Object[100];
Important that push checks that there is enough space, if not you have to double the stack size before push. Pushes should also not allow zero values as arguments, because now they should only be ignored.
Tips: System.arraycopy (...); Public interface for the class is known, but start writing the tests first.
Write tests: The tests will cover all scenarios (all possible ways you can use a stack). Since this is a generic class, test it for at least two different types (What if someone uses pop or peek on a blank stack?). Remember to include a test where the stack must be doubled to accommodate a new push (). Feel free to introduce a new public method capacity () that responds to the stack's current capacity. Also, create (if you haven't done) a constructor for the stack that takes in startup capacity (before you have one that creates a default capacity).
// GenericStack.java : Java program to create a Generic Stack using array
import java.util.Arrays;
public class GenericStack<T> {
private T list[]; // array to contain the elements of stack
private int top; // variable to contain the top index of stack
// default constructor to create an empty stack of 100 elements
public GenericStack()
{
list = (T[]) new Object[100];
top = -1;
}
// method to return the top element of stack if not empty else it returns null
public T peek() {
if(!isEmpty())
return list[top];
else
return null;
}
// method to push o to the top of stack , if o is not null
public void push(T o) {
if(o != null) // check if element to be inserted is not null
{
if(top == (list.length-1)) //check if stack is full, then expand the stack by twice its size
{
list = Arrays.copyOf(list, 2*(list.length)); // copies the elements of the list and creates and returns a new array of size 2*list.length
}
// push the element to top of stack
top++;
list[top] = o;
}
}
// method to remove and return the element from top of stack if not empty else return null
public T pop() {
if(!isEmpty()) //check if stack is not empty
{
// remove and return the top element
T o = list[top];
top--;
return o;
}
return null; // stack is empty
}
// method to check if the stack is empty
public boolean isEmpty() {
return(top == -1);
}
// method to return string representation of the stack
public String toString()
{
String str = "Stack: [";
for(int i=0;i<top;i++)
str += list[i]+", ";
str += list[top]+" ] ";
return str;
}
}
//end of GenericStack.java
//TestGenericStack .java : Driver program to test the GenericStack
public class TestGenericStack {
public static void main(String[] args) {
// test the stack for string and integer type
GenericStack<String> gsString = new GenericStack<>();
gsString.push("one");
gsString.push("two");
gsString.push("three");
gsString.push(null); // this is not inserted
System.out.println("Top element of Stack : "+gsString.peek());
while(!gsString.isEmpty())
System.out.println("Removing element :"+gsString.pop());
System.out.println("Trying to pop from an empty stack : "+gsString.pop()); // this should return null
GenericStack<Integer> gsInteger = new GenericStack<>();
gsInteger.push(1);
gsInteger.push(2);
gsInteger.push(3);
gsInteger.push(null); // this is not inserted
System.out.println("Top element of Stack : "+gsInteger.peek());
while (!(gsInteger.isEmpty())) {
System.out.println(gsInteger.pop());
}
System.out.println("Trying to peek from an empty stack : "+gsInteger.peek()); // this should return null
}
}
//end of TestGenericStack.java
Output: