package freer.Cupenoruler.ASCII_Player;/** * 環形緩衝器。邏輯上首尾銜接. * @author Cupenoruler * @version 2.0 */public class CircularBuffer<T>{/*************************************** * 為保證buffer的put和 get有序進行,用兩個索引 *putIndex�待填入元素空位的索引 *getIndex�待取出元素的索引 ***************************************/private intputIndex = 0;private intgetIndex = 0;private Object[] buffer= null;private intcapability = 0;//buffer容量/** * jsut for test~ * @param helloBaby */public static void main(String[] helloBaby){//CircularBuffer<String> a = new CircularBuffer<String>(1024);//System.out.println(a.putElement(null));//System.out.println(a.putElement("能存進去嗎?"));//System.out.println(a.getElement());//System.out.println(a.getElement());//System.out.println(a.getElementWithBlock());//System.out.println("如果控制台木有這條資訊,那麼上一句代碼造成阻塞了~");CircularBuffer<String> test = new CircularBuffer<String>(128);int i = 0;for(boolean canPut = true; canPut;){canPut = test.putElement("第" + (++i) + "個元素~~" );//System.out.println(canPut);}for(boolean canGet = true; canGet;) {String echoString = test.getElement();canGet = (null != echoString);if(canGet)System.out.println(echoString);}}/** * * @param capability 緩衝區大小 */public CircularBuffer(int capability){this.capability = capability;initialize();}/** * @param capability */private void initialize(){this.buffer = new Object[this.capability];}/** * 填入元素:注意此函數會造成阻塞 * @param element- 帶填入元素 */public void putElementWithBlock(T element){while(!putElement(element)){try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();System.out.println("put�߳��ж�");}}}/** * 取出元素,注意此函數會造成阻塞 */public T getElementWithBlock(){T temp = null;while(null == (temp = getElement()) ){try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();System.out.println("get�߳��ж�");}}return temp;}/** * 填入元素,此函數會立即返回 * @param element * @return true-操作成功 false-操作失敗(待填入資料的元素位還有資料) */public boolean putElement(T element){if(element == null)throw new NullPointerException("非要往裡邊填null嗎?");/* 不要覆蓋已有資料 */if(this.buffer[this.putIndex] != null){return false;}this.buffer[this.putIndex] = element;this.putIndex++;this.putIndex %= this.capability;return true;}/** * 取出元素,此函數會立即返回 * @return null-待取資料的元素位為null ,非null-成功取出資料 */@SuppressWarnings("unchecked")public T getElement(){if(this.buffer[this.getIndex] == null){return null;}//拿到引用,並將元素位置空Object temp = this.buffer[this.getIndex];this.buffer[this.getIndex] = null;this.getIndex++;this.getIndex %= this.capability;return (T)temp;}public void clear(){for(int i = 0, length = buffer.length; i < length; i++){buffer[i] = null;}this.putIndex = 0;this.getIndex = 0; }/****************************************************\ * --Setter and Getter--*\****************************************************/public int getCapability(){return capability;}// 新元素是以 索引0 向 索引length 的順序 put入 // 有鑒於此,這裡倒過來枚舉,防止出現“同向追趕”導致落空的的囧事;public boolean isEmputy(){ for(int i = this.buffer.length-1; i > 0; i--){ if( this.buffer[i] != null ){ return false; } } return true;}}