CharBuffer

image

CharBuffer

public abstract class CharBuffer extends Buffer implements Comparable<CharBuffer>, Appendable, CharSequence, Readable {
    /**
     * 間接buffer,使用heap buffers備份數組
    */
    final char[] hb;
    final int offset;
    boolean isReadOnly;

    CharBuffer(int mark, int pos, int lim, int cap, char[] hb, int offset) {
        super(mark, pos, lim, cap);
        this.hb = hb;
        this.offset = offset;
    }

    CharBuffer(int mark, int pos, int lim, int cap) {
        this(mark, pos, lim, cap, null, 0);
    }

    // 返回HeapCharBuffer
    public static CharBuffer allocate(int capacity) {
        if (capacity < 0)
            throw new IllegalArgumentException();
        return new HeapCharBuffer(capacity, capacity);
    }

    public static CharBuffer wrap(char[] array) {
        return wrap(array, 0, array.length);
    }

    public static CharBuffer wrap(char[] array, int offset, int length) {
        try {
            return new HeapCharBuffer(array, offset, length);
        } catch (IllegalArgumentException x) {
            throw new IndexOutOfBoundsException();
        }
    }

    public static CharBuffer wrap(CharSequence csq) {
        return wrap(csq, 0, csq.length());
    }

    /**
     * 返回StringCharBuffer
    */
    public static CharBuffer wrap(CharSequence csq, int start, int end) {
        try {
            return new StringCharBuffer(csq, start, end);
        } catch (IllegalArgumentException x) {
            throw new IndexOutOfBoundsException();
        }
    }

    /**
     * 判斷這個buffer是否有一個可存取的備份數組
    */
    public final boolean hasArray() {
        return (hb != null) && !isReadOnly;
    }

    /**
     * 返回這個buffer所使用的數組存儲空間的引用
    */
    public final char[] array() {
        if (hb == null)
            throw new UnsupportedOperationException();
        if (isReadOnly)
            throw new ReadOnlyBufferException();
        return hb;
    }

    /**
     * 數據在數組中存儲的開始位置的偏移量
    */
    public final int arrayOffset() {
        if (hb == null)
            throw new UnsupportedOperationException();
        if (isReadOnly)
            throw new ReadOnlyBufferException();
        return offset;
    }

    public int compareTo(CharBuffer that) {
        int n = this.position() + Math.min(this.remaining(), that.remaining());
        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
            int cmp = compare(this.get(i), that.get(j));
            if (cmp != 0)
                return cmp;
        }

        /**
         * 如果一個緩衝區在不相等元素髮現前已經被耗盡,較短的緩衝區被認爲是小於較長的緩衝區
        */
        return this.remaining() - that.remaining();
    }

    public boolean equals(Object ob) {
        if (this == ob)
            return true;
        if (!(ob instanceof CharBuffer))
            return false;
        CharBuffer that = (CharBuffer)ob;
        if (this.remaining() != that.remaining())
            return false;
        int p = this.position();
        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
            if (!equals(this.get(i), that.get(j)))
                return false;
        return true;
    }

    public CharBuffer get(char[] dst) {
        return get(dst, 0, dst.length);
    }

    public CharBuffer get(char[] dst, int offset, int length) {
        checkBounds(offset, length, dst.length);

        // 如果buffer中的數據不夠完全填滿數組,將產生異常
        if (length > remaining())
            throw new BufferUnderflowException();
        int end = offset + length;
        for (int i = offset; i < end; i++)
            dst[i] = get();
        return this;
    }

    public final CharBuffer put(char[] src) {
        return put(src, 0, src.length);
    }

    public CharBuffer put(char[] src, int offset, int length) {
        checkBounds(offset, length, src.length);

        // 如果buffer中沒有足夠的空間,將產生異常
        if (length > remaining())
            throw new BufferOverflowException();
        int end = offset + length;
        for (int i = offset; i < end; i++)
            this.put(src[i]);
        return this;
    }

    public CharBuffer put(CharBuffer src) {
        if (src == this)
            throw new IllegalArgumentException();
        if (isReadOnly())
            throw new ReadOnlyBufferException();
        int n = src.remaining();
        if (n > remaining())
            throw new BufferOverflowException();
        for (int i = 0; i < n; i++)
            put(src.get());
        return this;
    }

    public final CharBuffer put(String src) {
        return put(src, 0, src.length());
    }

    public CharBuffer put(String src, int start, int end) {
        checkBounds(start, end - start, src.length());
        if (isReadOnly())
            throw new ReadOnlyBufferException();
        if (end - start > remaining())
            throw new BufferOverflowException();
        for (int i = start; i < end; i++)
            this.put(src.charAt(i));
        return this;
    }

    public abstract CharBuffer duplicate();

    public abstract CharBuffer asReadOnlyBuffer();
}
兩個緩衝區被認爲相等的充要條件是:
  • 兩個對象類型相同。包含不同數據類型的 buffer 永遠不會相等,而且 buffer絕不會等於非 buffer 對象
  • 兩個對象都剩餘同樣數量的元素。 Buffer 的容量不需要相同,而且緩衝區中剩餘數據的索引也不必相同。但每個緩衝區中剩餘元素的數目(從位置到上界)必須相同
  • 在每個緩衝區中應被 get()函數返回的剩餘數據元素序列必須一致

HeapCharBuffer

class HeapCharBuffer extends CharBuffer {
    // 用於CharBuffer.allocate()
    HeapCharBuffer(int cap, int lim) {
        super(-1, 0, lim, cap, new char[cap], 0);
    }

    // 用於CharBuffer.wrap()
    HeapCharBuffer(char[] buf, int off, int len) {
        super(-1, off, off + len, buf.length, buf, 0);
    }

    /**
     * 只想從緩衝區中釋放一部分數據,而不是全部,然後重新填充
     * 丟棄已經釋放的數據,保留未釋放的數據,並使緩衝區對重新填充容量準備就緒
    */
    public CharBuffer compact() {
        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
        position(remaining());
        limit(capacity());
        discardMark();
        return this;
    }

    /**
     * 返回HeapCharBuffer
    */
    public CharBuffer duplicate() {
        return new HeapCharBuffer(hb, this.markValue(), this.position(), this.limit(), this.capacity(), offset);
    }

    /**
     * 返回HeapCharBufferR
    */
    public CharBuffer asReadOnlyBuffer() {
        return new HeapCharBufferR(hb, this.markValue(), this.position(), this.limit(), this.capacity(), offset);
    }

    /**
     * 創建一個從原始buffer的當前位置開始的新buffer,並且其容量是原始buffer的剩餘元素數量
    */
    public CharBuffer slice() {
        return new HeapCharBuffer(hb, -1, 0, this.remaining(), this.remaining(), this.position() + offset);
    }
}

HeapCharBufferR

class HeapCharBufferR extends HeapCharBuffer {
    protected HeapCharBufferR(char[] buf, int mark, int pos, int lim, int cap, int off) {
        super(buf, mark, pos, lim, cap, off);
        this.isReadOnly = true;
    }

    /**
     * 只讀,不允許任何put
    */
    public boolean isReadOnly() {
        return true;
    }

    public CharBuffer put(char x) {
        throw new ReadOnlyBufferException();
    }

    public CharBuffer put(int i, char x) {
        throw new ReadOnlyBufferException();
    }

    public CharBuffer put(char[] src, int offset, int length) {
        throw new ReadOnlyBufferException();
    }

    public CharBuffer put(CharBuffer src) {
        throw new ReadOnlyBufferException();
    }
}

StringCharBuffer

class StringCharBuffer extends CharBuffer {
    CharSequence str;

    StringCharBuffer(CharSequence s, int start, int end) {
        super(-1, start, end, s.length());
        int n = s.length();
        if ((start < 0) || (start > n) || (end < start) || (end > n))
            throw new IndexOutOfBoundsException();
        str = s;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章