Wednesday, September 22, 2010

ArrayDeque

ArrayDeque is an implementation of the 'Deque' interface i.e. java.util.ArrayDeque implements a double-ended queue, which allows efficient insertion and deletion at both ends. This an excellent choice for stacks and queues.
Double Ended Queue's extend 'Queue' and support adding and removing elements from both ends. In a Queue, you can add from one end and remove from the other. Also, Deque's can be used as a Queue and also a 'Stack'. ArrayDeque has no capacity restrictions like some other data structures (although you can specify that in one of its constructors). ArrayDeque is not threadsafe, as other collections like HashMap, et al. If you want it thread-safe, use 'LinkedBlockingQueue', which implements the 'BlockingQueue' interface, which further extends from 'Deque' interface.
An ArrayDeque has these characteristics:
  • Stack or queue. Supports operations to efficiently add, examine, or remove elements from either end.
  • Automatically expands as data is added to either the front or back. No capacity limit.
  • Good performance
    • Adding, examining, or deleting and element at either end of an ArrayDeque is O(1).
    • Generally faster than Stack.
    • Generally faster than LinkedList for queue operations.
  • Iteration - ArrayDeque implements Iterable, so can be traversed using a foreach loop or iterator. It also provides a descendingIterator() method for iterating in reverse order. So, a 'Deque' can be traversed from both directions programmatically using 'iterator' and 'descendingIterator' methods.
  • As with the other collections classes, only Object types are supported.
  • No indexed access is permitted.
  • No sorting is possible -- deques are not lists.
Deque vs LinkedList
 Deque is doubly linked and can be compared to 'LinkedList', which also implements a 'Deque', apart from List. In LinkedList, you can access an element randomly, by the element's index, which you cant do in Deque's. It was designed this way to make it more efficient.

Terminology

What are the ends called? The terminology of stacks and queues and lists is not standardized, so you'll see various terms for the ends.
  • Front = head = start = first.
  • Back = tail = end = last.

Common ArrayDeque methods and constructors

Here are some of the most useful ArrayDeque methods. Assume these declarations. Note that E is the notation for the type of an element in a collection.
int i;
boolean b;
ArrayDeque a;
E e;
Iterator iter;
E[] earray;
Object[] oarray;
ResultMethodDescription
Constructors
anew ArrayDeque()Creates ArrayDeque with initial default capacity.
anew ArrayDeque(cap)Creates ArrayDeque with initial int capacity cap.
anew ArrayDeque(coll)Creates ArrayDeque from the Collection coll.
Operations on the front (head, start, first)
a.addFront(e)adds e to the front of ArrayDeque a
b = a.offerFirst(e)Same as addFront. With capacity limited deques (not ArrayDeque) can return false.
e = a.getFirst()Returns, but does not remove, first element. Throws exception if deque is empty.
e = a.element()Same as getFirst.
e = a.peekFirst()Same as getFirst, but returns null if deque is empty.
e = a.peek()Same as peekFirst.
e = a.removeFirst()Returns and removes first element. Throws exception if deque is empty.
e = a.remove()Same as pollFirst.
e = a.pollFirst()Returns and removes first element. Returns null if deque is empty.
e = a.poll()Same as pollFirst.
e = a.pop()Same as removeFirst.
e = a.push(e)Same as addFront.
Operations on the back (tail, end, last)
a.addLast(e)adds e to the end of ArrayDeque a
a.add(e)Same as addLast.
b = a.offerLast(e)Same as addLast. With capacity limited deques (not ArrayDeque) can return false.
b = a.offer(e)Same as offerLast.
e = a.getLast()Returns, but does not remove, last element. Throws exception if deque is empty.
e = a.peekLast()Same as getLast, but returns null if deque is empty.
e = a.removeLast()Returns and removes last element. Throws exception if deque is empty.
e = a.pollLast()Returns and removes last element. Returns null if deque is empty.
Turning into an array
oarraya.toArray()Returns values in array of objects.
earraya.toArray(E[])The array parameter should be of the E class. Returns values in that array (or a larger array is allocated if necessary).
Iterators
itera.iterator()Returns an Iterator for forward traversal.
itera.descendingIterator()Returns an Iterator for backward traversal.
Searching
ba.contains(e)Returns true if ArrayDeque a contains e
ba.removeFirstOccurrence(e)Removes e from deque starting at beginning. Returns true if successful.
ba.removeLastOccurrence(e)Removes e from deque starting at end. Returns true if successful.
ba.remove(e)Same as removeFirstOccurrence().
Removing elements
Other
ia.size()Returns the number of elements in ArrayDeque a.
a.clear()removes all elements from ArrayDeque a

To get successive elements from an ArrayDeque - Several ways

Use either the foreach loop or an Iterator.
  1. foreach loop. This is fast and works for all kinds of lists, but is not entirely flexible (only sequential forward with no deletions, additions, or multiple references). This should be your first choice in programming. Works efficiently with both ArrayDeque and LinkedList.
    ArrayDeque a = new ArrayDeque();
    . . .
    for (String s : a) {
    System.out.println(s);
    }
  2. Iterator - Allows simple forward traversal. Can be used for the largest number of other kinds of data structures. This example uses an Iterator to print all elements (Strings) in an ArrayDeque. It uses hasNext(), which returns true if there are more elements, and next(), which returns the next element. Works with both ArrayDeque and LinkedList.
    for (Iterator iter = a.iterator(); iter.hasNext();  ) {
    System.out.println(iter.next());
    }
  3. ListIterator - Allows traversal of the ArrayDeque, but it is more general than a simple Iterator, allowing inserts and deletes (although both are very slow for an ArrayDeque). It also allows bidirectional traversal. Works efficiently with both ArrayDeque and LinkedList.

ArrayDeque example in java

package collection;

import java.util.ArrayDeque;
import java.util.Iterator;

public class ArrayDequeDemo
{
    public static void main(String[] args)
    {   
        ArrayDeque arrDeque = new ArrayDeque();

        arrDeque.add("mercedes");
        arrDeque.add("porsche");
        arrDeque.add("audi");

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        System.out.println();

        arrDeque.addLast("bmw");
        arrDeque.add("PORSCHE");
        arrDeque.addLast("Ferrari");

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        System.out.println();

        for(Iterator descendingIter = arrDeque.descendingIterator();descendingIter.hasNext();) {
            System.out.println(descendingIter.next());
        }

        System.out.println();
        System.out.println("First Element : " + arrDeque.getFirst());
        System.out.println("Last Element : " + arrDeque.getLast());
        System.out.println("Contains \"porsche\" : " + arrDeque.contains("porsche"));

        arrDeque.addFirst("porsche");

        System.out.println();

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        arrDeque.removeLastOccurrence("porsche");

        System.out.println();

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        arrDeque.removeFirstOccurrence("porsche");
        System.out.println();

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        System.out.println();
        System.out.println("Popped Element : " + arrDeque.pop());

        arrDeque.push("porsche");       
        System.out.println();

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        System.out.println("\n Size of Array Deck : " + arrDeque.size());

        System.out.println("\n Peek : " + arrDeque.peek());

        System.out.println("\n Peek First : " + arrDeque.peekFirst());
        System.out.println("\n Peek Last : " + arrDeque.peekLast());

        System.out.println();

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        System.out.println("\n Poll First : " + arrDeque.pollFirst());
        System.out.println("\n Poll Last : " + arrDeque.pollLast());

        System.out.println();

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        System.out.println("\n Poll : " + arrDeque.poll());

        System.out.println("\n Peek First : " + arrDeque.peekFirst());
        System.out.println("\n Peek Last : " + arrDeque.peekLast());

        arrDeque.offerFirst("porsche");
        arrDeque.offerLast("what the heck?");

        System.out.println();

        for(Iterator iter = arrDeque.iterator();iter.hasNext();) {
            System.out.println(iter.next());
        }

        System.out.println("\n Get First : " + arrDeque.getFirst());
        System.out.println("\n Get Last : " + arrDeque.getLast());

        System.out.println("\n Element : " + arrDeque.element());

        Object[] objArray = arrDeque.toArray();
        System.out.println("\n Object Array Size : " + objArray.length);

        String[] strArray = (String[]) arrDeque.toArray(new String[0]);
        System.out.println("\n String Array Size : " + strArray.length);

        ArrayDeque arrDequeClone = arrDeque.clone();
        System.out.println("Clone Size : " + arrDequeClone.size());

        System.out.println("arrDeque == arrDequeClone : " + (arrDeque == arrDequeClone));

        System.out.println("arrDeque.equals(arrDequeClone) : " + arrDeque.equals(arrDequeClone));
    }
}

See Oracle/Sun's website for more on this.

No comments:

Post a Comment

Chitika