【Java源码分析】为什么不可以在指定默认容量的ArrayList对象中插入元素

【Java源码分析】为什么不可以在指定默认容量的ArrayList对象中插入元素

问题描述

执行以下代码会报异常 java.lang.IndexOutOfBoundsException: Index: 5, Size: 0

@Test
public void test(){
    ArrayList<Integer> list = new ArrayList<Integer>(10);
    list.add(5, 1);
}

查看源码分析

当执行 ArrayList list = new ArrayList(10);时,会调用ArrayList的构造方法,其源码如下

 public ArrayList(int initialCapacity) {
     if (initialCapacity > 0) {
         this.elementData = new Object[initialCapacity];
     } else if (initialCapacity == 0) {
         this.elementData = EMPTY_ELEMENTDATA;
     } else {
         throw new IllegalArgumentException("Illegal Capacity: "+
                                            initialCapacity);
     }
 }

可见,ArrayList确实是创建了长度为指定容量10的数组。
但是执行 list.add(5, 1); 时抛出了索引越界异常。
为什么无法在下标为5处插入元素呢?
我们来看看add的源代码

public void add(int index, E element) {
    rangeCheckForAdd(index);

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}

add 方法体中的第一行是 rangeCheckForAdd(index);
它是一个验证索引的方法,具体代码如下

private void rangeCheckForAdd(int index) {
    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

当我们执行 list.add(5, 1);的时候,会把 5 传递给 index。
而此时,list中还没有元素,size = 0。
因此,index > size条件成立,就执行 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));


解决办法

使用Integer数组操作,然后转换为ArrayList对象

 @Test
 public void test02(){
     Integer[] array = new Integer[10];
     array[5] = 1;
     ArrayList<Integer> list = new ArrayList<>(Arrays.asList(array));
     System.out.println(list);
 }

执行结果如下:

[null, null, null, null, null, 1, null, null, null, null]

参考:

ArrayList源代码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值