1. 程式人生 > >Java實現環形佇列

Java實現環形佇列

這裡我定義的環形佇列為:列表中最後一個元素是指向列表中的第一個元素,而且裡面提供一個next方法,可以不斷獲取下一個元素,在環形佇列中也就是不斷的轉圈,實現方式如下:

佇列中提供的方法:

public boolean add(E e):加入佇列
public E next():加入返回當前指標元素並把指標指向下一個元素
public E prev():返回當前元素,並把指標指向上一個元素
remove(E e):刪除佇列中某一個元素

完整的實現程式碼如下:

public class CircularQueue<E> {
    private int size;

    //指標
private Node<E> node; private Node<E> first; private Node<E> last; private final int MODE_NEXT = 0; private final int MODE_PREV = 1; private int lastMode = MODE_NEXT; //最後一次操作,0為next,1為prev public CircularQueue() { } /** * 加入佇列 * @param
e */
public boolean add(E e){ final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, first); last = newNode; if (node == null) node = newNode; //指標 if (l == null) { first = newNode; first.prev = first; } else
{ l.next = newNode; first.prev = l.next; } size++; return true; } /** * 返回當前指標元素並把指標指向下一個元素 * @return */ public E next() { if (node == null) { return null; } E e = node.item; node = node.next; lastMode = MODE_NEXT; return e; } /** * 返回當前元素,並把指標指向上一個元素 * @return */ public E prev() { if (node == null) { return null; } E e = node.item; node = node.prev; lastMode = MODE_PREV; return e; } /** * 刪除佇列中某一個元素 * @param e * @return */ public boolean remove(E e) { if (e == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (e.equals(x.item)) { unlink(x); return true; } } } size--; return true; } public E peek(){ return node.item; } /** * 刪除節點 */ E unlink(Node<E> x) { final E element = x.item; final Node<E> next = x.next; final Node<E> prev = x.prev; if (prev == x || next == x) { this.first = null; this.last = null; this.node = null; } next.prev = prev; prev.next = next; if ((element==null&&this.node.item==null) || (element.equals(this.node.item))) { this.node = lastMode==MODE_NEXT ? this.node.next : this.node.prev; } x.item = null; x = null; size--; return element; } public int size() { return size; } /** * 節點類 * @param <E> */ private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } } }

如果在高併發的情況下需要實現執行緒同步的環形佇列,只需要繼承上面的類,為需要同步的方法加鎖即可:

import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by giant039 on 2017/3/17.
 */
public class CircularBlockingQueue<E> extends CircularQueue<E> {
    /** 對新增,刪除,指標移動操作加鎖 */
    protected final ReentrantLock putLock = new ReentrantLock();

    private QueueListener listener;

    public CircularBlockingQueue() {
        super();
    }

    public CircularBlockingQueue(QueueListener listener) {
        super();
        this.listener = listener;
    }

    public void setListener(QueueListener listener) {
        this.listener = listener;
    }

    @Override
    public boolean add(E e) {
        final ReentrantLock putLock = this.putLock;
        try {
            putLock.lockInterruptibly();
            super.add(e);

            if (listener != null) listener.afterAdd(e);

            return true;
        } catch (InterruptedException exp) {
            exp.printStackTrace();
            return false;
        } finally {
            putLock.unlock();
        }

    }

    @Override
    public E next() {
        final ReentrantLock putLock = this.putLock;
        try {
            putLock.lockInterruptibly();
            return super.next();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        } finally {
            putLock.unlock();
        }

    }

    @Override
    public E prev() {
        final ReentrantLock putLock = this.putLock;
        try {
            putLock.lockInterruptibly();
            return super.prev();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        } finally {
            putLock.unlock();
        }
    }

    @Override
    public boolean remove(E e) {
        final ReentrantLock putLock = this.putLock;
        try {
            putLock.lockInterruptibly();

            if (listener != null) listener.afterAdd(e);

            return super.remove(e);
        } catch (InterruptedException exp) {
            exp.printStackTrace();
            return false;
        } finally {
            putLock.unlock();
        }
    }


    /**
     * 監聽器監聽插入,刪除,等操作之後需要實現的功能
     */
    interface QueueListener<E> {
        void afterAdd(E e);
        void afterRemove(E e);
    }

}