Java - Stack Example
Java - Stack Example
Stack class is in java.util package of java. Stack works like last in first out policy. Stack does not require any fix dimension like String array and int array. Stack contains many useful methods. To add element in Stack, we can use push() method of Stack class. To get value from Stack, Stack provides pop() method and Stack size() method. Size() method returns total number of elements in Stack. peek() method looks at the object at the top of this stack without removing it from the stack Stack Example
import java.util.Iterator; import java.util.Stack; public class StackExample { public static void main(String[] args) { Stack<String> sk=new Stack<String>(); sk.push("a"); sk.push("c"); sk.push("e"); sk.push("d"); Iterator it=sk.iterator(); System.out.println("Size before pop() :"+sk.size()); while(it.hasNext()) { String iValue=(String)it.next(); System.out.println("Iterator value :"+iValue); } // get and remove last element from stack String value =(String)sk.pop(); System.out.println("value :"+value); System.out.println("Size After pop() :"+sk.size()); } }
Output Size before pop() :4 Iterator value :a Iterator value :c Iterator value :e Iterator value :d value :d Size After pop() :3
Output Initial Size of Queue :5 Queue Next Value :b Queue Next Value :a Queue Next Value :c Queue Next Value :e Queue Next Value :d Queue peek :b
// add vector elements vc.add("Vector Object 1"); vc.add("Vector Object 2"); vc.add("Vector Object 3"); vc.add("Vector Object 4"); vc.add("Vector Object 5"); // add vector element at index vc.add(3, "Element at fix position"); // vc.size() inform number of elements in Vector System.out.println("Vector Size :"+vc.size()); // get elements of Vector for(int i=0;i<vc.size();i++) { System.out.println("Vector Element "+i+" :"+vc.get(i)); } } }
output ArrayList Size :6 ArrayList Element 0 :First Element ArrayList Element 1 :Second Element ArrayList Element 2 :Fixed Order of Element ArrayList Element 3 :Third Element ArrayList Element 4 :forth Element ArrayList Element 5 :fifth Element
Generics
Using generics allows you to define classes that can work with any defined type. This is very similar to the use of templates in C++. When you use collections like the vector and the stack you do not have to do any typecasting to get the correct value. This ensures that you cannot make silly errors with getting items from a collection. Without generics we had to use typecasting to get the correct data out of structures. The other problem is we are going to have problems if try to add the wrong data type. Generics ensure that we use the right data type and that we do not have any typecasting to do. If we use the wrong data type then the program will not compile. Example:
Vector<Integer> v = new Vector<Integer>();
The vector is a class that uses generics. The above line declares a vector that can only function on integer objects. If we try to add a String object we will get an error. Try this:
v.add("james");
This occurs because when I created the Vector it was compiled in a way that it can only use Integers. Anything else crashes at compilation. So if you use the wrong data type you will get an error at compile time instead of running time. Making it easier to find your error.
Creating generic classes
We can make our own generic classes. To do this we are going to make our own Stack class it is going to be a very simple Stack. If you don't know, the Stack is a structure that has restricted access. You can only access the top item of the Stack. The stack provides a first-in, last-out order meaning you can only access the top item of the stack. See my tutorial here: http://forum.codecal...447-stacks.html to see more information on the stack. Are stack class is only going to push items onto the stack and remove items from the stack. Our stack will use a Vector as the underlying structure so it will be able to resize. Note that we cannot use an array as the underlying structure? Why? This is because generic classes are compiled at runtime and the parameters are replaced with the appropriate type. However, arrays are initalized with a type at declaration and thus they cannot be generic. So
our underlying structure will be a vector. Creating a stack is really easy. All we need is a member variable that keeps track of the index of the top item. We store all the items in a private vector but only provide a method that can access the top item of the stack. The use of the private keyword in front of the Vector is what makes this structure possible. If we didn't include it then we would just be creating a wrapper of the Vector and what is the purpose of that?
Creating the stack
To define that our stack is generic we use angle brackets after the class name and in those brackets we place the names of different parameters. These parameters will define what type of data the stack holds. So the class skeleton looks like this:
public class Stack<E> { }
Now what instance members do we need? We need a vector, and a counter for the index of the top. That is all. The vector will be of type E indicating that it holds a user defined data type and the index variable will be an integer set to -1. So add these just after the class declaration.
private Vector<E> stack; // holds the contents of the stack private int top; // the index of the top item in the stack. -1 indicates empty.
We create a new Vector that is empty, this is going to hold the stack. We will initalize the top variable to -1 which indicates that the stack is empty. Now the next two methods we will define are push and pop. The push method adds an item to the top of the stack and the pop method removes an item from the stack and returns it. The push method:
public void push(E obj) { stack.add(obj); top++; }
We use the add method in the vector to add the parameter to the stack. The parameter is of type E which will be replaced with the type defined by the programmer when it is used. We increase the top variable by 1 so we have the index of the top item stored. The pop method is very similar to this, it returns type E and returns the item at the top of the stack. However we have to remove this item from the stack so we need to store it in a temporary variable. We can't just do
return stack.get(top);
Why? We have to do two other things, decrease the top variable by 1 so it points to the new top of the stack. We also have to remove the item from the Vector. If we don't we will run into problems if we add a new item later. We will see this item again which is not what we want. The problem with this I illustrated in my tutorial about Vectors. We have to copy the vector contents into a new array every time we erase the end item. This can take a really long time for big stacks. We will only remove an item from the Stack if it is not empty. The pop method returns null if the stack is empty. So the pop method looks like this:
public E pop() { if (top == -1) { return null; // stack is empty } E temp = stack.get(top); stack.remove(top); top--; return temp; }
This covers everything the Stack needs to do but it might be useful to define two methods that check if the stack is empty and how many items are in the stack. The stack is empty if top = -1. So the empty method looks like this:
public boolean isEmpty(){ return top == -1; }
The number of items in the stack then is top+1. If the stack is empty (top = -1) and the number of items is 0.
public int size() { return top+1; }
top--; return temp; } public boolean isEmpty(){ return top == -1; } public int size() { return top+1; } }
import java.util.PriorityQueue; public class Test { public static void main(String[] args) { Comparator<String> comparator = new StringLengthComparator(); PriorityQueue<String> queue = new PriorityQueue<String>(10, comparator); queue.add("short"); queue.add("very long indeed"); queue.add("medium"); while (queue.size() != 0) { System.out.println(queue.remove()); } } } // StringLengthComparator.java import java.util.Comparator; public class StringLengthComparator implements Comparator<String> { @Override public int compare(String x, String y) { // Assume neither string is null. Real code should // probably be more robust if (x.length() < y.length()) { return -1; } if (x.length() > y.length()) { return 1; } return 0; } }
subSet public SortedSet subSet(Object fromElement, Object toElement) Returns a view of the portion of this sorted set whose elements range from fromElement, inclusive, to toElement, exclusive.
headSet public SortedSet headSet(Object toElement) Returns a view of the portion of this sorted set whose elements are strictly less than toElement. The returned sorted set is backed by this sorted set, so changes in the returned sorted set are reflected in this sorted set, and vice-versa. The returned sorted set supports all optional set operations. tailSet public SortedSet tailSet(Object fromElement) Returns a view of the portion of this sorted set whose elements are greater than or equal to fromElement. The returned sorted set is backed by this sorted set, so changes in the returned sorted set are reflected in this sorted set, and vice-versa. The returned sorted set supports all optional set operations.
Important "Backed Collection" Methods for TreeSet and TreeMap Method Description headSet(e, b*) Returns a subset ending at element e and exclusive of e headMap(k, b*) Returns a submap ending at key k and exclusive of key k tailSet(e, b*) Returns a subset starting at and inclusive of element e tailMap(k, b*) Returns a submap starting at and inclusive of key k subSet(s, b*, e, b*) Returns a subset starting at element s and ending just before element e subMap(s, b*, e, b*) Returns a submap starting at key s and ending just before key s