数组与ArrayList

这一段是废话……

做这个总结,主要是今天才发现之前一直忽略的一个小问题。我们写算法的时候,总是用C语言写。习惯用JAVA,也习惯用封装类在逻辑层面写代码,具体的算法用的就很少了。于是,走了一圈,又回到基本的数据类型上写细节的部分。


数组变量指向的是某一连续的内存空间的首地址。而ArrayList的底层是由数组实现的,与数组最主要的区别是,数组在声明的时候要指出其size,而ArrayList是可变长度的数组。且ArrayList里面封装了一些有用的方法,用起来比较方便,如public boolean contains(Object o)、public int indexOf(Object o)等。至于add、remove之类的是由其高矮胖瘦随意可变的本质决定的嘛~

逻辑好混乱的说。。。首先,为了说明数组和ArrayList有差别,先看这段简单的代码,主要是比较两者在赋值和索引上面的区别。

		long startTime = System.currentTimeMillis();
		System.out.println("startTime:" + startTime);
		List list = new ArrayList();
		int a[] = new int[60000];
		for(int i = 0; i<60000; i++)
		{
		//	list.add(i);
			a[i] = i;
		}
		long endTime = System.currentTimeMillis();
		System.out.println("endTime:" + endTime + " used time:" + (endTime-startTime));
		        //  + a.);
		
		for(int i = 0; i<60000; i++)
		{
		//	list.get(i);
			int b = a[i];
		}
		long findTime = System.currentTimeMillis();
		System.out.println("findTime:" + findTime + " used time:" + (findTime-endTime));

ArrayList的结果如下:

startTime:1354110283709
endTime:1354110283715 used time:6
findTime:1354110283716 used time:1
数组结果如下:
 startTime:1354110318600
endTime:1354110318602 used time:2
findTime:1354110318603 used time:1

可见,两者在索引上没有多大区别;主要是赋值上。实际上,在ArrayList初始化时,指定size为60000,结果与数组一致。

下面,看一下ArrayList里面的add是如何实现的。

    public boolean add(E e) {
	ensureCapacity(size + 1);  // Increments modCount!!
	elementData[size++] = e;
	return true;
    }


    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;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
	}
    }
由上知道,ArrayList在扩容时,按照当前容量的3/2+1来扩充的,然后还会做一次复制工作,所以比较耗时。

 

计算一下,ArrayList会赋值多少次:

注意,ArrayList的无参构造函数的初始容量是10.

                int i = 10;
		long sum = 60000;
		int count = 0;
		while(i<6000)
		{
			i = (i * 3)/2 + 1;
			sum += (i-1);
			count++;
		}
		System.out.println("i=" + i + ",sum=" + sum + ",count=" + count);
结果是sum=83169,count=16。所以,会进行16次扩容,赋值操作为83169次。

综上,还是用ArrayList方便,因为你可以在初始化时指定其size。

参考资料:JAVA中ArrayList和Vector区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值