ArrayList扩容问题

最近在看jdk的源码,看到ArrayList的时候发现一个问题,在插入的时候,如果进行扩容,会进行两次数组的copy。



 

第一次:

public void ensureCapacity(int minCapacity) {
	modCount++;
	int oldCapacity = elementData.length;
	if (minCapacity > oldCapacity) {
	    Object oldData[] = elementData;
	    int newCapacity = (oldCapacity * 3)/2 + 1;
    	    if (newCapacity < minCapacity)
		newCapacity = minCapacity;
            // 在此把整个数组copy到一个新的数组
            elementData = Arrays.copyOf(elementData, newCapacity);
	}
    }

 第二次拷贝:

public void add(int index, E element) {
	if (index > size || index < 0)
	    throw new IndexOutOfBoundsException(
		"Index: "+index+", Size: "+size);
	
	// 如果数组长度不足,将进行扩容
	ensureCapacity(size+1);  // Increments modCount!!
        // copy发生在这里,index后边的数据都需要再次copy
	System.arraycopy(elementData, index, elementData, index + 1,
			 size - index);
	elementData[index] = element;
	size++;
    }

 从代码可以看到,从插入点index后边的数据如果需要扩容,则会拷贝两次。一次为拷贝到新的数组,一次为整体向后挪一位。

后来考虑是不是可以创建新数组的时候拷贝两次,把index以前的数据先copy到新数组,然后index以后的数据直接向后挪一位copy入新的数组。


 

修改后的代码:

	public void add(int index, E element) {
		if (index > size || index < 0)
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
					+ size);

		// 如果数组长度不足,将进行扩容
		// ensureCapacity(size+1); // Increments modCount!!

		int minCapacity = size + 1;
		modCount++;
		int oldCapacity = elementData.length;
		Object[] newObj = null;
		if (minCapacity > oldCapacity) {
			Object oldData[] = elementData;
			int newCapacity = (oldCapacity * 3) / 2 + 1;
			if (newCapacity < minCapacity)
				newCapacity = minCapacity;
			newObj = new Object[newCapacity];
		}
		if (newObj != null) {
			System.arraycopy(elementData, 0, newObj, 0, index);
			System.arraycopy(elementData, index, newObj, index + 1, size
					- index);
			elementData = newObj;
		} else {
			System.arraycopy(elementData, index, elementData, index + 1, size
					- index);
		}
		elementData[index] = element;
		size++;
	}

 
 因环境问题,过段时间找台测试机器把测试结果贴出来。目前在本机测效率无提升,不知道是因为机器上东西太多还是因为这个思路本身不对。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值