首页

基于mina-core源码包的CircularQueue分享其自定义实现循环Queue队列

标签:CircularQueue,自定义queue,mina,apache,循环队列     发布时间:2017-12-17   

一、前言

基于mina-core(2.0.4)包中的org.apache.mina.util.CircularQueue继承AbstractList实现可循环Queue,具体实现内容如下所示

二、源码说明

package org.apache.mina.util;@b@@b@import java.io.Serializable;@b@import java.util.AbstractList;@b@import java.util.Arrays;@b@import java.util.NoSuchElementException;@b@import java.util.Queue;@b@@b@public class CircularQueue<E> extends AbstractList<E>@b@  implements Queue<E>, Serializable@b@{@b@  private static final long serialVersionUID = 3993421269224511264L;@b@  private static final int DEFAULT_CAPACITY = 4;@b@  private final int initialCapacity;@b@  private volatile Object[] items;@b@  private int mask;@b@  private int first;@b@  private int last;@b@  private boolean full;@b@  private int shrinkThreshold;@b@@b@  public CircularQueue()@b@  {@b@    this(4);@b@  }@b@@b@  public CircularQueue(int initialCapacity)@b@  {@b@    this.first = 0;@b@    this.last = 0;@b@@b@    int actualCapacity = normalizeCapacity(initialCapacity);@b@    this.items = new Object[actualCapacity];@b@    this.mask = (actualCapacity - 1);@b@    this.initialCapacity = actualCapacity;@b@    this.shrinkThreshold = 0;@b@  }@b@@b@  private static int normalizeCapacity(int initialCapacity)@b@  {@b@    int actualCapacity = 1;@b@    do {@b@      if (actualCapacity >= initialCapacity) break label21;@b@      actualCapacity <<= 1; }@b@    while (actualCapacity >= 0);@b@    actualCapacity = 1073741824;@b@@b@    label21: return actualCapacity;@b@  }@b@@b@  public int capacity()@b@  {@b@    return this.items.length;@b@  }@b@@b@  public void clear()@b@  {@b@    if (!(isEmpty())) {@b@      Arrays.fill(this.items, null);@b@      this.first = 0;@b@      this.last = 0;@b@      this.full = false;@b@      shrinkIfNeeded();@b@    }@b@  }@b@@b@  public E poll()@b@  {@b@    if (isEmpty()) {@b@      return null;@b@    }@b@@b@    Object ret = this.items[this.first];@b@    this.items[this.first] = null;@b@    decreaseSize();@b@@b@    if (this.first == this.last) {@b@      this.first = (this.last = 0);@b@    }@b@@b@    shrinkIfNeeded();@b@    return ret;@b@  }@b@@b@  public boolean offer(E item) {@b@    if (item == null) {@b@      throw new IllegalArgumentException("item");@b@    }@b@@b@    expandIfNeeded();@b@    this.items[this.last] = item;@b@    increaseSize();@b@    return true;@b@  }@b@@b@  public E peek()@b@  {@b@    if (isEmpty()) {@b@      return null;@b@    }@b@@b@    return this.items[this.first];@b@  }@b@@b@  public E get(int idx)@b@  {@b@    checkIndex(idx);@b@    return this.items[getRealIndex(idx)];@b@  }@b@@b@  public boolean isEmpty()@b@  {@b@    return ((this.first == this.last) && (!(this.full)));@b@  }@b@@b@  public int size()@b@  {@b@    if (this.full) {@b@      return capacity();@b@    }@b@@b@    if (this.last >= this.first) {@b@      return (this.last - this.first);@b@    }@b@@b@    return (this.last - this.first + capacity());@b@  }@b@@b@  public String toString()@b@  {@b@    return "first=" + this.first + ", last=" + this.last + ", size=" + size() + ", mask = " + this.mask;@b@  }@b@@b@  private void checkIndex(int idx)@b@  {@b@    if ((idx < 0) || (idx >= size()))@b@      throw new IndexOutOfBoundsException(String.valueOf(idx));@b@  }@b@@b@  private int getRealIndex(int idx)@b@  {@b@    return (this.first + idx & this.mask);@b@  }@b@@b@  private void increaseSize() {@b@    this.last = (this.last + 1 & this.mask);@b@    this.full = (this.first == this.last);@b@  }@b@@b@  private void decreaseSize() {@b@    this.first = (this.first + 1 & this.mask);@b@    this.full = false;@b@  }@b@@b@  private void expandIfNeeded() {@b@    if (this.full)@b@    {@b@      int oldLen = this.items.length;@b@      int newLen = oldLen << 1;@b@      Object[] tmp = new Object[newLen];@b@@b@      if (this.first < this.last) {@b@        System.arraycopy(this.items, this.first, tmp, 0, this.last - this.first);@b@      } else {@b@        System.arraycopy(this.items, this.first, tmp, 0, oldLen - this.first);@b@        System.arraycopy(this.items, 0, tmp, oldLen - this.first, this.last);@b@      }@b@@b@      this.first = 0;@b@      this.last = oldLen;@b@      this.items = tmp;@b@      this.mask = (tmp.length - 1);@b@      if (newLen >>> 3 > this.initialCapacity)@b@        this.shrinkThreshold = (newLen >>> 3);@b@    }@b@  }@b@@b@  private void shrinkIfNeeded()@b@  {@b@    int size = size();@b@    if (size <= this.shrinkThreshold)@b@    {@b@      int oldLen = this.items.length;@b@      int newLen = normalizeCapacity(size);@b@      if (size == newLen) {@b@        newLen <<= 1;@b@      }@b@@b@      if (newLen >= oldLen) {@b@        return;@b@      }@b@@b@      if (newLen < this.initialCapacity) {@b@        if (oldLen == this.initialCapacity) {@b@          return;@b@        }@b@@b@        newLen = this.initialCapacity;@b@      }@b@@b@      Object[] tmp = new Object[newLen];@b@@b@      if (size > 0)@b@        if (this.first < this.last) {@b@          System.arraycopy(this.items, this.first, tmp, 0, this.last - this.first);@b@        } else {@b@          System.arraycopy(this.items, this.first, tmp, 0, oldLen - this.first);@b@          System.arraycopy(this.items, 0, tmp, oldLen - this.first, this.last);@b@        }@b@@b@@b@      this.first = 0;@b@      this.last = size;@b@      this.items = tmp;@b@      this.mask = (tmp.length - 1);@b@      this.shrinkThreshold = 0;@b@    }@b@  }@b@@b@  public boolean add(E o)@b@  {@b@    return offer(o);@b@  }@b@@b@  public E set(int idx, E o)@b@  {@b@    checkIndex(idx);@b@@b@    int realIdx = getRealIndex(idx);@b@    Object old = this.items[realIdx];@b@    this.items[realIdx] = o;@b@    return old;@b@  }@b@@b@  public void add(int idx, E o)@b@  {@b@    if (idx == size()) {@b@      offer(o);@b@      return;@b@    }@b@@b@    checkIndex(idx);@b@    expandIfNeeded();@b@@b@    int realIdx = getRealIndex(idx);@b@@b@    if (this.first < this.last) {@b@      System.arraycopy(this.items, realIdx, this.items, realIdx + 1, this.last - realIdx);@b@    }@b@    else if (realIdx >= this.first) {@b@      System.arraycopy(this.items, 0, this.items, 1, this.last);@b@      this.items[0] = this.items[(this.items.length - 1)];@b@      System.arraycopy(this.items, realIdx, this.items, realIdx + 1, this.items.length - realIdx - 1);@b@    }@b@    else {@b@      System.arraycopy(this.items, realIdx, this.items, realIdx + 1, this.last - realIdx);@b@    }@b@@b@    this.items[realIdx] = o;@b@    increaseSize();@b@  }@b@@b@  public E remove(int idx)@b@  {@b@    if (idx == 0) {@b@      return poll();@b@    }@b@@b@    checkIndex(idx);@b@@b@    int realIdx = getRealIndex(idx);@b@    Object removed = this.items[realIdx];@b@@b@    if (this.first < this.last) {@b@      System.arraycopy(this.items, this.first, this.items, this.first + 1, realIdx - this.first);@b@    }@b@    else if (realIdx >= this.first) {@b@      System.arraycopy(this.items, this.first, this.items, this.first + 1, realIdx - this.first);@b@    }@b@    else {@b@      System.arraycopy(this.items, 0, this.items, 1, realIdx);@b@      this.items[0] = this.items[(this.items.length - 1)];@b@      System.arraycopy(this.items, this.first, this.items, this.first + 1, this.items.length - this.first - 1);@b@    }@b@@b@    this.items[this.first] = null;@b@    decreaseSize();@b@@b@    shrinkIfNeeded();@b@    return removed;@b@  }@b@@b@  public E remove() {@b@    if (isEmpty())@b@      throw new NoSuchElementException();@b@@b@    return poll();@b@  }@b@@b@  public E element() {@b@    if (isEmpty())@b@      throw new NoSuchElementException();@b@@b@    return peek();@b@  }@b@}