Java语言进阶:Buffer类(缓冲区)

Java语言进阶:Buffer类(缓冲区)


Buffer类(缓冲区)

概述:Buffer是一个抽象类,它是对某种基本类型的数组进行了封装。

作用: 在NIO中,就是通过 Buffer 来读写数据的。所有的数据都是用Buffer来处理的,它是NIO读写数据的中转池, 通常使用字节数组。

Buffer主要有如下几种:

  • ByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

创建ByteBuffer

路径

  • 创建ByteBuffer对象的三种方式

讲解

  • ByteBuffer类内部封装了一个byte[]数组,并可以通过一些方法对这个数组进行操作。

  • 创建ByteBuffer对象

    • 方式一:在堆中创建缓冲区:allocate(int capacity)

      public static void main(String[] args) {
          	//创建堆缓冲区
              ByteBuffer byteBuffer = ByteBuffer.allocate(10);
      }
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XmnmM9iK-1653718194143)(img/17.png)]

    • 方式二: 在系统内存创建缓冲区:allocatDirect(int capacity)

      public static void main(String[] args) {
          	//创建直接缓冲区
              ByteBuffer byteBuffer = ByteBuffer.allocateDirect(10);
      }
      
      • 在堆中创建缓冲区称为:间接缓冲区

      • 在系统内存创建缓冲区称为:直接缓冲区

      • 间接缓冲区的创建和销毁效率要高于直接缓冲区

      • 间接缓冲区的工作效率要低于直接缓冲区

  • 方式三:通过数组创建缓冲区:wrap(byte[] arr)

       public static void main(String[] args) {
              byte[] byteArray = new byte[10];
              ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
       }
    
    • 此种方式创建的缓冲区为:间接缓冲区

添加数据-put

讲解

  • public ByteBuffer put(byte b):向当前可用位置添加数据。

  • public ByteBuffer put(byte[] byteArray):向当前可用位置添加一个byte[]数组

  • public ByteBuffer put(byte[] byteArray,int offset,int len):添加一个byte[]数组的一部分

    public static void main(String[] args) {
            yteBuffer b1 = ByteBuffer.allocate(10);
            // 添加数据
            b1.put((byte)11);
            b1.put((byte)12);
            b1.put((byte)13);
    
            // ByteBuffer转换为普通字节数组
            byte[] bytes = b1.array();
            System.out.println(Arrays.toString(bytes));
            // 打印结果: [11, 12, 13, 0, 0, 0, 0, 0, 0, 0]
    }
    
    public class Test_添加数据 {
        public static void main(String[] args) {
            ByteBuffer b1 = ByteBuffer.allocate(10);
            // 添加数据
            b1.put((byte)11);
            b1.put((byte)12);
            b1.put((byte)13);
    
            // ByteBuffer转换为普通字节数组
            byte[] bytes = b1.array();
            System.out.println(Arrays.toString(bytes));
            //打印结果: [11, 12, 13, 0, 0, 0, 0, 0, 0, 0]
    
            System.out.println("=======================");
            byte[] b2 = {14,15,16};
            // 添加数据
            b1.put(b2);
            // ByteBuffer转换为普通字节数组
            byte[] b = b1.array();
            System.out.println(Arrays.toString(b));
            //打印结果: [11, 12, 13, 14, 15, 16, 0, 0, 0, 0]
        }
    }
    
    
    public class Test_添加数据 {
        public static void main(String[] args) {
            ByteBuffer b1 = ByteBuffer.allocate(10);
            // 添加数据
            b1.put((byte)11);
            b1.put((byte)12);
            b1.put((byte)13);
    
            // ByteBuffer转换为普通字节数组
            byte[] bytes = b1.array();
            System.out.println(Arrays.toString(bytes));
            // 打印结果: [11, 12, 13, 0, 0, 0, 0, 0, 0, 0]
    
            System.out.println("=======================");
            byte[] b2 = {14,15,16};
            // 添加数据
            b1.put(b2,0,1);
            // ByteBuffer转换为普通字节数组
            byte[] b = b1.array();
            System.out.println(Arrays.toString(b));
            // 打印结果: [11, 12, 13, 14, 0, 0, 0, 0, 0, 0]
        }
    }
    

容量-capacity

讲解

  • Buffer的容量(capacity)是指:Buffer所能够包含的元素的最大数量。定义了Buffer后,容量是不可变的。

  • 示例代码:

    public static void main(String[] args) {
        ByteBuffer b1 = ByteBuffer.allocate(10);
        System.out.println("容量:" + b1.capacity());//10。之后不可改变
    
        byte[] byteArray = {97, 98, 99, 100};
        ByteBuffer b2 = ByteBuffer.wrap(byteArray);
        System.out.println("容量:" + b2.capacity());//4。之后不可改变
    }
    
  • 结果:

    容量:10
    容量:4
    

限制-limit

讲解

  • 限制limit是指:第一个不应该读取或写入元素的index索引。缓冲区的限制(limit)不能为负,并且不能大于容量。

  • 有两个相关方法:

    • public int limit():获取此缓冲区的限制。
    • public Buffer limit(int newLimit):设置此缓冲区的限制。
  • 示例代码:

    public class Test_添加数据 {
        public static void main(String[] args) {
            ByteBuffer b1 = ByteBuffer.allocate(10);
            // 添加数据
            b1.put((byte)10);
    
            // 获取限制
            int limit1 = b1.limit();
            System.out.println("limit1:"+limit1);// 10
    
            // 设置限制
            b1.limit(3);
    
            // 添加元素
            b1.put((byte)20);
          b1.put((byte)30);
            // b1.put((byte)40);// 报异常,因为限制位置索引为3,所以再存14就会报异常:BufferOverflowException
    
        }
    }
    

在这里插入图片描述


位置-position

讲解

  • 位置position是指:当前可写入的索引。位置不能小于0,并且不能大于"限制"。

  • 有两个相关方法:

    • public int position():获取当前可写入位置索引。
    • public Buffer position(int p):更改当前可写入位置索引。
  • 示例代码:

    public class Test_添加数据 {
        public static void main(String[] args) {
            ByteBuffer b1 = ByteBuffer.allocate(10);
            // 添加数据
            b1.put((byte)11);
    
            // 获取当前位置索引
            int position = b1.position();
            System.out.println("position:"+position);// 1
    
            // 设置当前位置索引
            b1.position(5);
    
            b1.put((byte)22);
            b1.put((byte)33);
            System.out.println("position:"+b1.position());// 7
            System.out.println(Arrays.toString(b1.array()));
            // 打印结果:[11, 0, 0, 0, 0, 22, 33, 0, 0, 0]
        }
    }
    

小结

  • 注意: 字节缓冲数组能操作的范围就是position位置到limit位置:[position,limit)
    

标记-mark

讲解

  • 标记mark是指:当调用缓冲区的reset()方法时,会将缓冲区的position位置重置为该索引。

  • 相关方法:

    • public Buffer mark():设置此缓冲区的标记为当前的position位置。
    • public Buffer reset() : 将此缓冲区的位置重置为以前标记的位置。
  • 示例代码:

    public static void main(String[] args) {
            ByteBuffer b1 = ByteBuffer.allocate(10);
            // 添加数据
            b1.put((byte)11);
    
            // 获取当前位置索引
            int position = b1.position();
            System.out.println("position:"+position);// 1
    
            // 标记当前位置索引
            b1.mark();
    
            // 添加元素
            b1.put((byte)22);
            b1.put((byte)33);
    
            // 获取当前位置索引
            System.out.println("position:"+b1.position());// 3
            System.out.println(Arrays.toString(b1.array()));
            // 打印结果:[11, 22, 33, 0, 0, 0, 0, 0, 0, 0]
    
            // 重置当前位置索引
            b1.reset();
            // 获取当前位置索引
            System.out.println("position:"+b1.position());// 1
    
            // 添加元素
            b1.put((byte)44);
            System.out.println(Arrays.toString(b1.array()));
            // 打印结果:[11, 44, 33, 0, 0, 0, 0, 0, 0, 0]
    
        }
    

其它方法

讲解

- public int remaining():获取position与limit之间的元素数。
- public boolean isReadOnly():获取当前缓冲区是否只读。
- public boolean isDirect():获取当前缓冲区是否为直接缓冲区。
- public Buffer rewind():重绕此缓冲区。
  - 将position位置设置为:0
  - 限制limit不变。
  - 丢弃标记。
- public Buffer clear():还原缓冲区的状态。
  - 将position设置为:0
  - 将限制limit设置为容量capacity;
  - 丢弃标记mark。
- public Buffer flip():缩小limit的范围。
  - 将limit设置为当前position位置;
  - 将当前position位置设置为0- 丢弃标记。
package com.itheima.demo11_ByteBuffer常用方法;

import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * @Author:pengzhilin
 * @Date: 2020/9/23 15:33
 */
public class Test6_clear和flip {
    public static void main(String[] args) {
        /*
            - public Buffer clear():还原缓冲区的状态。
              - 将限制limit设置为容量capacity;
              - 将position设置为:0
              - 丢弃标记mark。

            - public Buffer flip():缩小limit的范围。
              - 将limit设置为当前position位置;
              - 将当前position位置设置为0;
              - 丢弃标记。
         */
        // 创建ByteBuffer字节缓冲数组
        ByteBuffer b = ByteBuffer.allocate(10);

        // 容量:10,限制:10,位置:0
        System.out.println("容量:" + b.capacity() + ",限制:" + b.limit() + ",位置:" + b.position());

        // 往b添加数据
        b.put((byte) 10);
        b.put((byte) 20);
        b.put((byte) 30);

        // 容量:10,限制:10,位置:3
        System.out.println("容量:" + b.capacity() + ",限制:" + b.limit() + ",位置:" + b.position());
        System.out.println(Arrays.toString(b.array()));// [10, 20, 30, 0, 0, 0, 0, 0, 0, 0]


        /*// 调用clear
        b.clear();
        // 容量:10,限制:10,位置:0
        System.out.println("容量:"+b.capacity()+",限制:"+b.limit()+",位置:"+b.position());
        System.out.println(Arrays.toString(b.array()));// [10, 20, 30, 0, 0, 0, 0, 0, 0, 0]
        */

        // 调用flip()
        b.flip();
        // 容量:10,限制:3,位置:0
        System.out.println("容量:"+b.capacity()+",限制:"+b.limit()+",位置:"+b.position());
        System.out.println(Arrays.toString(b.array()));// [10, 20, 30, 0, 0, 0, 0, 0, 0, 0]

    }
}


笔记如有错误之处,请各位大佬指正,欢迎评论留言,不胜感激!!!


  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值