Java 8 ArrayList初始容量中断?
今天我在克隆ArrayList时遇到了一个奇怪的问题。
我读了this的答案并试了一下。然而,我收到了一个ArrayOutOfBounds例外。所以我更仔细地研究了一下,似乎是ArrayList<>;(整数大小)不起作用
这是已知的问题吗
测试等级:
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class ArrayListTest {
@Test
public void test() {
List<String> lista = new ArrayList<>();
lista.add("a");
List<String> listb = new ArrayList<>(lista.size());
System.out.println("Size of lista: " + lista.size());
System.out.println("Size of listb: " + listb.size());
}
}
困难阶层:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
public class ArrayListTest2 {
@Test
public void test() {
List<String> lista = new ArrayList<>();
lista.add("a");
List<String> listb = new ArrayList<>(lista.size());
Collections.copy(listb, lista);
System.out.println("Lista: " + lista);
System.out.println("Listb: " + listb);
}
}
其结果是:
java.lang.IndexOutOfBoundsException: Source does not fit in dest
at java.util.Collections.copy(Collections.java:556)
at ArrayListTest2.test(ArrayListTest2.java:13)
有什么想法吗
# 1 楼答案
这确实是
Collections.copy()
文档的一个问题。它的JDK 8 documentation上写着:这使用了“long”和“longer”这两个术语,它们似乎指的是列表的长度。但是,如果您查看
List
规范,没有关于长度的定义,但是有关于大小的定义,在ArrayList
中,有关于容量的定义。目前还不清楚Collections.copy()
是根据列表的大小还是容量来定义的事实上,}的{a2}已修改为:
Collections.copy()
应该用列表的大小来定义。{ArrayList
构造函数的arg设置其初始容量,而不是大小。大小是列表中当前存在的元素数Collections.copy()
要求目标列表的大小大于或等于源列表的大小。这就是为什么当你试图将一个大小为1的列表复制到一个大小为0的列表时,会得到IndexOutOfBoundsException
# 2 楼答案
如果目标列表太小。我将抛出IndexOutOfBoundsException
# 3 楼答案
我认为你对^{的理解有问题。就像初始化一个用“null”值填充的基元数组一样,在初始化
ArrayList
过程中不会发生类似的情况。通过设置n
的initialCapacity
,您所做的就是让编译器知道它应该为n
对象分配足够的内存。请注意,即使已经分配了内存,列表的大小仍然是0,因为其中没有元素关于
copy()
。您正在尝试将lista
复制到初始容量为lista.size() = 0
的列表中。那里好像有什么不对劲吗这种混淆可能是因为文档中没有提到
size
这个词,但这是这里的关键因素