There is no such thing as a stack queue
— they are completely different things. You are trying to program a Stack
. And you can't really call a Stack
general purpose: it's a specialized collection that supports the last in, first out (LIFO) principle.
So I guess that by "general purpose" you meant able to work with objects of all types.
The solution to that is called Generics and you should study them thoroughly. Basically, a generic class will accept one or more type arguments when instantiated:
Stack<Integer> stack = new Stack<Integer>();
Stack<String> anotherStack = new Stack<String>();
This means every Stack
will only accept elements of one type, protecting type safety:
stack.push(5000); // allowed
stack.push("hi"); // compiler error
anotherStack.push(5000); // compiler error
anotherStack.push("hi"); // allowed
System.out.println(stack.pop()); // prints 5000
So bearing that in mind, let's take a look at your code. When re-implementing a class that already exists, it's a good idea to take a look at the original. As you can see, it makes use of a Vector
. That's a growable array of objects — the perfect starting point for your own implementation of Stack
.
So let's start off by changing this:
GeneralStack [] stack;
To this (we'll come back to the type parameter, E
, later):
private Vector<E> stack;
A quick question to ask in between: Why would anyone, ever want to limit the size of a Stack
? I think you misunderstood the int capacity
argument on many of the Java collections. It isn't an upper limit; it's the initial size to prevent re-allocating the interally used array too often. So let's get rid of the DEFAULT_CAPACITY
and let Vector
handle that for us — the same thing applies to count
.
The methodsisEmpty()
and size()
(renamed from getCount()
to match the standard naming) can now delegate their work to Vector.isEmpty()
and Vector.size()
.
And push
can change to this:
public void push(E value) {
stack.add(value);
}
Never throw an IllegalArgumentException
if you are accepting no arguments. An EmptyStackException
would be much more appropriate:
public E pop() {
if (isEmpty())
throw new EmptyStackException();
return stack.remove(stack.size() - 1);
}
Your method topVal()
should really be called peek()
and follow the same principles when it comes to throwing exceptions. Note how convenient the Vector.lastElement()
method comes in here:
public E peek() {
if (isEmpty())
throw new EmptyStackException();
return stack.lastElement();
}
Time to finally come back to the type parameters. Change your class definition to the following:
public class Stack<E> implements Iterable<E> {
The <E>
means your Stack
will accept one type parameter (you can reference it in your methods, as shown above). The implementation of Iterable:
@Override
public Iterator<E> iterator() {
return stack.iterator();
}
allows your Stack
to be used in a foreach loop:
for (int element : stack){
System.out.println(element);
}
A few more notes about your original code. Try to simplify as far as possible. For instance, this madness:
//accessor isEmpty
public boolean isEmpty ()
{
boolean isEmpty=false;
if (count == 0);
{
isEmpty=true;
}
return isEmpty;
}
should be written as:
public boolean isEmpty()
{
return count > 0;
}
Note that I removed all your comments because they are absolutely useless noise. Try to only write comments if you have something meaningful to say that can't be expressed in the code (or that is valuable to the caller). And try to adopt the standard Java code style.
All the above suggestions would lead to something like this:
import java.util.EmptyStackException;
import java.util.Iterator;
import java.util.Vector;
public class Stack<E> implements Iterable<E> {
private Vector<E> stack;
public Stack() {
stack = new Vector<E>();
}
public Stack(int capacity) {
stack = new Vector<E>(capacity);
}
public int size() {
return stack.size();
}
public boolean isEmpty() {
return stack.isEmpty();
}
public void push(E value) {
stack.add(value);
}
public E pop() {
if (isEmpty())
throw new EmptyStackException();
return stack.remove(stack.size() - 1);
}
public E peek() {
if (isEmpty())
throw new EmptyStackException();
return stack.lastElement();
}
@Override
public Iterator<E> iterator() {
return stack.iterator();
}
}
Usage
Stack<Integer> stack = new Stack<Integer>();
stack.push(5);
stack.push(3);
stack.push(10);
int result = stack.pop();
System.out.println(result); // 10
for (int element : stack){
System.out.println(element); // 5, 3
}
System.out.println(stack.peek()); // 3
System.out.println(stack.isEmpty()); // false
stack.pop();
stack.pop();
stack.pop(); // EmptyStackException