关于数组的赋值问题

关于数组的赋值问题

java的基础语法已经学习完了,上了某个自学网站回顾了一下,有个自制StringBuffer和String比较性能的作业,就尝试了一下,途中踩了一点坑,写个博客记录一下。

这里我参考了一下StringBuffer的源码编写一下insert方法,发现,当程序执行到到14行的时候,JVM虚拟机抛出了一个java.lang.ArrayIndexOutOfBoundsException给我,当时很困惑,debug半天没发现问题

1 public void insert(int pos, String b) {
2       /*判断边界条件*/
3        if (pos < 0) return;
4        if (pos > length) return;
5        //如果现在数组的长度加上新增字符串的长度大于原先设定的容量,扩容
6        while (length + b.length() > capacity) {
7            capacity = (int) (length + b.length() * 1.5f);
8            char[] newValue = new char[capacity];
9            System.arraycopy(value, 0, newValue, 0, value.length);
10            value = newValue;
11       }
12        char[] cs = b.toCharArray();
13        //将要插入的位置后面的字符向后挪
14        System.arraycopy(value, pos, value, pos + cs.length, length - pos);
15        //把要插入的数据插入到指定位置
16        System.arraycopy(cs, 0, value, pos, cs.length);
17        length += length + cs.length;

后来当我每个位置都判断了一下我设定的容量大小和数组长度之后,终于发现问题,在15行,我的字符数组长度和我设定的初始容量不相符,所以导致了越界,我又翻回前面查找错误。

1 public void insert(int pos, String b) {
2        System.out.println("capacity.."+capacity);//16
3        /*判断边界条件*/
4        if (pos < 0) return;
5        if (pos > length) return;
6        //如果现在数组的长度加上新增字符串的长度大于原先设定的容量,扩容
7        while (length + b.length() > capacity) {
8            capacity = (int) (length + b.length() * 1.5f);
9            char[] newValue = new char[capacity];
10            System.arraycopy(value, 0, newValue, 0, value.length);
11            value = newValue;
12        }
13        char[] cs = b.toCharArray();
14        //把已存在的数据往后推
15        System.out.println("value.length..." + value.length);//4
16        System.out.println("pos+cs.length..." + (pos + cs.length));//4
17        System.out.println("pos+cs.length是否大于value.length..." + ((pos + cs.length) > value.length));//false
17        System.arraycopy(value, pos, value, pos + cs.length, length - pos);//程序运行到这里会抛出异常
19        //把要插入的数据插入到指定位置
20        System.arraycopy(cs, 0, value, pos, cs.length);
21        length += length + cs.length;
22    }

这里是我设定的初始容量,和实例化类的同时初始化一个数组

1   int capacity = 16;
2   int length = 0;
3   char[] value;
4
5   public MyStringBuffer() {
6       //建立新的数组
7       value = new char[capacity];
8		length = value.length;//16
9   }

下面是在初始化MyStringBuffer之后,在构造方法里面添加要存入的字符串,this()是调用了上面的构造方法。
通过检查各部分的变量值发现,在第7行这个地方,value.length的长度变成了4,数组的初始容积仍然为16。而上面初始化的时候,value.length的长度是16。

1 public MyStringBuffer(String str) {
2        this();
3		//非空判断
4        if (null == str) return;
5        value = str.toCharArray();
6        length = value.length;
7        System.out.println("赋值后的length..." + length);//4
8        System.out.println("赋值后的容量...  " + capacity);//16
9		//边界条件判断
10        if (capacity < value.length) {
11            capacity = value.length * 2;
12            value = new char[capacity];
13        }
14        if (capacity >= str.length()) {
15            System.arraycopy(str.toCharArray(), 0, value, 0, str.length());//如果大于存入的长度,就赋值数组
16        }
17    }

这时候我才发现,所有的坑,都集中在第5行上面。

1 public MyStringBuffer(String str) {
2        this();
3		//非空判断
4        if (null == str) return;
5        value = str.toCharArray();
6        length = value.length;

这里的value虽然在之前初始化了,但是,由于str.toCharArray()返回的也是一个字符数组,相当于value重新指向了一个长度为4的字符数组,导致了后面在做字符插入的时候越界了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值