对我来说,这是一个值得关注的问题,因为它在stackoverflow备受关注和推荐。提出这样问题的人受到广泛称赞,这使得他能够在stackoverflow上做很多事情。虽然这对我来说并没有太大的意义,但我们还是先来看看这个问题。
问题如下:如何将下面的数组array转换为一个ArrayList。
Element[] array = {new Element(1), new Element(2), new Element(3)};
1. 最受欢迎和接受度最高的答案
最受欢迎和接受度最高的答案如下:
ArrayList<Element> arrayList = new ArrayList<Element>(Arrays.asList(array));
首先,我们来看一下Java文档中ArrayList的构造方法:
ArrayList
-ArrayList(Collection c)
创建一个包含指定集合内所有元素的list,其中元素的顺序是按指定集合的iterator来定的
所以,构造函数完成的工作如下:
1. 将集合c转换为一个数组array
2. 将数组array复制到ArrayList内部名为“elementData"的数组中
如果现在调用add()方法,elementData数组的长度导致其无法再添加一个新的元素。因此,要把该数组复制到一个更大的数组中。如下代码所示,新数组的长度为原数组的1.5倍。
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通常和实际大小很接近
}
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
2. 第二受欢迎的答案
第二受欢迎的答案是:
List<Element> list = Arrays.asList(array);
因为asList()方法返回的list的大小是固定的,所以该方法不是最好的。正如我们知道的,ArrayList必须由array来实现,而由asList()方法返回固定长度的list,该list依赖于原始数组,这样的话,对返回的list执行添加或移除元素时,会抛出UnsupportedOperationException异常。
list.add(new Element(4));
Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList at collection. ConvertArray.main(ConvertArray.java:22)
3. 该问题的启示
这个问题并不难,还有点儿意思。每一个Java程序员都知道ArrayList,虽然它用起来很简单,但也容易犯上述错误。我猜这就是该问题受欢迎的原因。其他针对某范围的Java类库的类似的问题很难如此受欢迎。
同一个问题有多种不同的答案。这对许多问题来说都是真理,我猜人们并不关心这一问题,他们只是喜欢回答问题!