Buffer的属性
容量(capacity):缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能被改变
上界(limit):缓冲区的第一个不能被读或写的元素。或者说,缓冲区中现存元素的计数。(要是position已经到达limit的位置,此时再调用get()方法会报IndexOutOfBoundsException异常)
位置(position):下一个要被读或写的元素的索引。位置会自动由相应的 get( )和 put( )函数更新
标记(mark):下一个要被读或写的元素的索引。
*记住以下公式:
0 <= mark <= position <= limit <= capacity
Buffer的常用操作
clear(),compact(),flip(),rewind()
一旦读完Buffer中的数据,需要让Buffer准备好再次被写入。可以通过clear()或compact()方法来完成。
如果调用的是clear()方法,position将被设回0,limit被设置成 capacity的值。换句话说,Buffer 被清空了。Buffer中的数据并未清除,只是这些标记告诉我们可以从哪里开始往Buffer里写数据。
如果Buffer中有一些未读的数据,调用clear()方法,数据将“被遗忘”,意味着不再有任何标记会告诉你哪些数据被读过,哪些还没有。
如果Buffer中仍有未读的数据,且后续还需要这些数据,但是此时想要先先写些数据,那么使用compact()方法。
compact()方法将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据。
public static void main(String[] args) {
CharBuffer buf = CharBuffer.allocate(24);
buf.put("hello world");
buf.clear();
buf.put("world hello");
for(int i=0;i<buf.capacity();i++) {
System.out.print(buf.get(i));
}
}
运行结果:
public static void main(String[] args) {
CharBuffer buf = CharBuffer.allocate(24);
buf.put("hello world");
buf.compact();
buf.put("world hello");
for(int i=0;i<buf.capacity();i++) {
System.out.print(buf.get(i));
}
}
运行结果:
mark(),reset()
通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position。
public static void main(String[] args) {
CharBuffer buffer = CharBuffer.allocate(10);
buffer.put('你');
buffer.put('好');
// 经过标记后,会持续记住此位置
buffer.position(0).mark();
while(buffer.hasRemaining()) {
System.out.println(buffer.get());
// mark将会跳转到上次标记的位置
buffer.reset();
}
}
上述的程序将会持续输出“你”字,并进入无穷循环。
equals(),compareTo()
可以使用equals()和compareTo()方法两个Buffer。
equals()
当满足下列条件时,表示两个Buffer相等:
有相同的类型(byte、char、int等)。
Buffer中剩余的byte、char等的个数相等。
Buffer中所有剩余的byte、char等都相同。
如你所见,equals只是比较Buffer的一部分,不是每一个在它里面的元素都比较。实际上,它只比较Buffer中的剩余元素。
compareTo()
compareTo()方法比较两个Buffer的剩余元素(byte、char等), 如果满足下列条件,则认为一个Buffer“小于”另一个Buffer:
第一个不相等的元素小于另一个Buffer中对应的元素 。
所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)。(剩余元素是从 position到limit之间的元素)