IntBuffer
1.从一个demo来看IntBuffer。
import java.nio.IntBuffer; import java.security.SecureRandom;
public class IntBufferDemo {
public static void main(String[] args) { IntBuffer buffer = IntBuffer.allocate(10); System.out.println("capacity: "+ buffer.capacity());
for(int i = 0; i < 5; i++) { int randomNum = new SecureRandom().nextInt(20); buffer.put(randomNum); }
System.out.println("before flip limit: "+ buffer.limit());
buffer.flip(); System.out.println("after flip limit: " + buffer.limit());
System.out.println("enter while loop");
while(buffer.hasRemaining()) { System.out.println("position: "+buffer.position()); System.out.println("limit: "+buffer.limit()); System.out.println("capacity: "+buffer.capacity());
System.out.println(buffer.get()); } } } |
(1)IntBuffer buffer = IntBuffer.allocate(10);
//这里传递的值为10 public static IntBuffer allocate(int capacity) { if (capacity < 0) throw new IllegalArgumentException(); return new HeapIntBuffer(capacity, capacity); } //cap = 10, limit = 10 HeapIntBuffer(int cap, int lim) { // package-private super(-1, 0, lim, cap, new int[cap], 0); } //mark = -1 pos=0 hb = new int[10] offset=0 IntBuffer(int mark, int pos, int lim, int cap, // package-private int[] hb, int offset) { super(mark, pos, lim, cap); this.hb = hb; this.offset = offset; } Buffer(int mark, int pos, int lim, int cap) { // package-private if (cap < 0) throw new IllegalArgumentException("Negative capacity: " + cap); this.capacity = cap; //10 limit(lim); //10 position(pos); //0 if (mark >= 0) { if (mark > pos) throw new IllegalArgumentException("mark > position: (" + mark + " > " + pos + ")"); this.mark = mark; } } |
从最初申请buffer我们可以看出:
①capacity:即Buffer容量,我们设定为10;
②limit: 即无法读取或者写的索引,初始化与capacity一样值。
③Position:默认值0;表示下一个要读取/写的索引。
④mark:已经读或者写的索引(初始未定义)
mark <= 0 <=position<=limit<=capacity
(2)put方法往数组中存放值,每一次Put都要将position++;但是最多加到limit
public IntBuffer put(int x) { hb[ix(nextPutIndex())] = x; return this; } final int nextPutIndex() { // package-private if (position >= limit) throw new BufferOverflowException(); return position++; } //在我们初始化的时候offset默认值为0 protected int ix(int i) { return i + offset; } |
(3) flip()方法
public final Buffer flip() { limit = position; //将position的值保持到limit position = 0; //将position设置为0 mark = -1; //mark设置为-1 return this; } |
(4) buffer的get方法
public int get() { return hb[ix(nextGetIndex())]; } //将Position+1,但是不能超过Limit final int nextGetIndex() { // package-private if (position >= limit) throw new BufferUnderflowException(); return position++; } |
(5) buffer的clear方法
public final Buffer clear() { position = 0; //将position设置为0 limit = capacity; //limit设置为数组的容量 mark = -1; //已读或者写索引下表标记为-1 return this; } |
通过以上分析,我们明白了nio为啥既可以读,又可以写。用position,limit,mark,capacity4个变量,记录了读到了什么位置,最多读取多少条记录Limit,数组容量多大。写到了什么位置,最多写到哪。