这一段是废话……
做这个总结,主要是今天才发现之前一直忽略的一个小问题。我们写算法的时候,总是用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。