Abstract Queue in Java

In Java, the Queue interface is used to represent a collection of elements arranged in a specific order. One of the concrete implementations of the Queue interface is the AbstractQueue class, which provides a skeletal implementation of the Queue interface. In this article, we will discuss the AbstractQueue class in detail and its various methods and properties.

Overview of AbstractQueue class

The AbstractQueue class is an abstract class that provides a skeletal implementation of the Queue interface. It implements all the methods of the Queue interface except for the add(), remove(), and element() methods. These methods are implemented as abstract methods, which must be overridden by the concrete implementations of the AbstractQueue class.

The AbstractQueue class extends the AbstractCollection class, which provides a skeletal implementation of the Collection interface. The AbstractQueue class provides additional methods for manipulating the queue, such as offer(), peek(), poll(), and remove().

Methods of AbstractQueue class

  1. offer(E e): This method adds the specified element to the queue if it is possible to do so immediately without violating capacity restrictions. It returns true if the element was added successfully, and false otherwise.
  2. peek(): This method retrieves, but does not remove, the head of the queue. It returns null if the queue is empty.
  3. poll(): This method retrieves and removes the head of the queue, or returns null if the queue is empty.
  4. remove(): This method retrieves and removes the head of the queue. It throws a NoSuchElementException if the queue is empty.
  5. add(E e): This method adds the specified element to the queue if it is possible to do so immediately without violating capacity restrictions. It throws an IllegalStateException if the element cannot be added at this time due to capacity restrictions.
  6. remove(Object o): This method removes the specified element from the queue, if it is present. It returns true if the element was removed successfully, and false otherwise.
  7. contains(Object o): This method returns true if the queue contains the specified element, and false otherwise.
  8. isEmpty(): This method returns true if the queue is empty, and false otherwise.
  9. size(): This method returns the number of elements in the queue.

Implementing AbstractQueue class

To implement the AbstractQueue class, we need to extend it and provide implementations for the add(), remove(), and element() methods. Here is an example of a simple implementation of the AbstractQueue class:

import java.util.AbstractQueue;
import java.util.Iterator;

public class MyQueue extends AbstractQueue {
@Override
public boolean offer(E e) {
    // add the element to the queue
    return true;
}

@Override
public E peek() {
    // retrieve the head of the queue
    return null;
}

@Override
public E poll() {
    // retrieve and remove the head of the queue
    return null;
}

@Override
public Iterator<E> iterator() {
    // return an iterator over the elements in the queue
    return null;
}

@Override
public int size() {
    // return the size of the queue
    return 0;
}
}


In this example, we have implemented the offer(), peek(), poll(), iterator(), and size() methods.


To complete the implementation of the AbstractQueue class, we need to provide implementations for the add(), remove(), and element() methods. Here is an example of how to do this:

import java.util.AbstractQueue;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyQueue extends AbstractQueue {
private Node<E> head;
private Node<E> tail;
private int size;

public MyQueue() {
    head = null;
    tail = null;
    size = 0;
}

@Override
public boolean offer(E e) {
    Node<E> node = new Node<>(e);
    if (tail == null) {
        head = node;
        tail = node;
    } else {
        tail.next = node;
        tail = node;
    }
    size++;
    return true;
}

@Override
public E peek() {
    if (head == null) {
        return null;
    }
    return head.element;
}

@Override
public E poll() {
    if (head == null) {
        return null;
    }
    E result = head.element;
    head = head.next;
    if (head == null) {
        tail = null;
    }
    size--;
    return result;
}

@Override
public Iterator<E> iterator() {
    return new QueueIterator<>(head);
}

@Override
public int size() {
    return size;
}

@Override
public boolean add(E e) {
    if (offer(e)) {
        return true;
    } else {
        throw new IllegalStateException("Queue full");
    }
}

@Override
public E remove() {
    E result = poll();
    if (result == null) {
        throw new NoSuchElementException();
    }
    return result;
}

@Override
public E element() {
    E result = peek();
    if (result == null) {
        throw new NoSuchElementException();
    }
    return result;
}

private static class Node<E> {
    E element;
    Node<E> next;

    Node(E element) {
        this.element = element;
        this.next = null;
    }
}

private static class QueueIterator<E> implements Iterator<E> {
    private Node<E> current;

    QueueIterator(Node<E> head) {
        current = head;
    }

    @Override
    public boolean hasNext() {
        return current != null;
    }

    @Override
    public E next() {
        if (current == null) {
            throw new NoSuchElementException();
        }
        E result = current.element;
        current = current.next;
        return result;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }
}
}


In this example, we have implemented the add(), remove(), and element() methods using the offer(), poll(), and peek() methods respectively. We have also added a Node class to represent the elements of the queue, and a QueueIterator class to provide an iterator over the elements in the queue.

Conclusion

The AbstractQueue class provides a skeletal implementation of the Queue interface, which can be extended to implement various types of queues. It provides a set of methods for manipulating the queue, such as offer(), peek(), poll(), and remove(). By extending the AbstractQueue class, we can implement these methods and provide a concrete implementation of the Queue interface.