ByteBuffer 中可以通过4个索引高效操作数据,它们分别是:mark(标记)、position(位置)、limit(界限)、capacity(容量)。
下表是具体操作这些索引的方法:
方法名 | 用途 |
capacity() | 返回缓冲区容量 |
clear() | 清空缓冲区,将 position 设置为0,limit 设置为 capacity。可以通过此方法覆写缓冲区 |
flip() | 将 limit 设置为 position ,position 设置为0。此方法用于准备从缓冲区读取数据 |
limit() | 返回 limit 的值 |
limit(int newLimit) | 设置 limit 的值 |
mark() | 将 mark 设置为 position |
position() | 返回 position 的值 |
position(int newPosition) | 设置 position 的值 |
remaining() | 返回 ( limit - newPosition ) |
hasRemaining() | 若有介于 postion 和 limit 之间的元素,则返回 true |
初看这些方法可能会有点摸不着头脑,下面我们一起学习一个简单的例子:交换相邻字符,以便于加深理解。
public class UsingBuffers {
private static void symmetricScramble(CharBuffer buffer) {
while (buffer.hasRemaining()) {
//设置标记
buffer.mark();
//获取后续2个字符
char c1 = buffer.get();
char c2 = buffer.get();
//将position设置为mark
buffer.reset();
//交替覆写字符
buffer.put(c2).put(c1);
}
}
public static void main(String[] args) {
char[] data = "UsingBuffers".toCharArray();
//创建指定大小的缓冲器
ByteBuffer bb = ByteBuffer.allocate(data.length * 2);
CharBuffer cb = bb.asCharBuffer();
//写入数据
cb.put(data);
System.out.println(cb.rewind());
//交换相邻字符
symmetricScramble(cb);
System.out.println(cb.rewind());
//再次交换相邻字符
symmetricScramble(cb);
System.out.println(cb.rewind());
}
}
UsingBuffers
sUniBgfuefsr
UsingBuffers
因一个 char 类型占2个字节,故创建 char 个数 * 2 字节大小的缓冲器,刚好能容纳所有字符。
缓冲器创建好时如下图:
position 指向第一个元素,capacity 和 limit 指向最后一个元素。
当我们调用 get() 和 put() 方法时,position 指针会依次向后移动,但通过指定下标的方式调用 get(int index)
和 put(int index, char c)
并不会改变下标的位置。
在 while 循环中,使用 mark() 将 mark 标记为 position 的位置时,缓冲器如下图:
调用2次 get() 方法后,position 指针向后移动2次, position 此时的位置如下图:
为了能够交换2个相邻位置的值,我们需要把 c2 写入前一个位置, c1 写入后一个位置,这里可以使用 put(int index, char c)
指定绝对位置来实现,但本例通过 reset() 方法,把 position 设置为 mark 的位置,再重新依次覆写,已达到相同的目的,如下图所示:
之后,进入下一个循环,在此将 mark 设置到 position 的位置。
等循环完成,position 会移动至缓冲器末尾。
如果需要打印出缓冲器中的全部内容,则需要调用 rewind() 将 position 移动至起始位置,此方法同时也会舍弃 mark 标记。
此时再打印 CharBuffer 会得到 position 至 limit 之间的全部内容,再次调用 symmetricScramble() 则可以将交换后的内容复原。
本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。
若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!