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);
}
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);
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);
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 {
HeapCharBuffer(int cap, int lim) {
super(-1, 0, lim, cap, new char[cap], 0);
}
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;
}
}