今天,当我遇到一个奇怪的问题时,我正在寻找克隆一个ArrayList。
我看了this回答并试了一下。但是,我收到了一个ArrayOutOfBounds异常。所以我看了一下,显然ArrayList<>(int size)不起作用了?
这是一个已知的问题吗?
测试类:
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不适合dest
在java.util.Collections.copy(Collections.java:556)
在ArrayListTest2.test(ArrayListTest2.java:13)
有什么想法吗?
答案 0 :(得分:4)
这对Collections.copy()
的文档确实存在问题。其JDK 8 documentation说:
目的地列表必须至少与源列表一样长。如果它更长,则目标列表中的其余元素不受影响。
这使用术语&#34; long&#34;并且&#34;更长&#34;这似乎是指列表的长度。但是,如果查看List
规范,则没有 length 的定义 - 但 size 的定义和ArrayList
中的定义,容量。目前还不清楚Collections.copy()
是否根据列表的 size 或 capacity 进行了定义。
事实上,Collections.copy()
应根据列表的 size 来定义。 Collections.copy()
的{{3}}已修改为:
目的地列表的大小必须大于或等于源列表的大小。如果它更大,则目标列表中的其余元素不受影响。
ArrayList
构造函数的arg设置其初始容量,而不是 size 。 size 是列表中当前存在的元素数。 Collections.copy()
要求目标列表的大小更大或更符合源的大小。这就是当您尝试将大小为1的列表复制到大小为0的列表时获得IndexOutOfBoundsException
的原因。
答案 1 :(得分:0)
如果目标List太小。我将抛出IndexOutOfBoundsException。
import java.util.*;
public class CollectionsDemo {
public static void main(String args[]) {
// create two lists
List<String> srclst = new ArrayList<String>(5);
List<String> destlst = new ArrayList<String>(10);
// populate two lists
srclst.add("a");
srclst.add("b");
srclst.add("d");
destlst.add("e");
destlst.add("f");
destlst.add("g");
// copy into dest list
Collections.copy(destlst, srclst);
System.out.println("Value of source list: "+srclst);
System.out.println("Value of destination list: "+destlst);
}
答案 2 :(得分:0)
我认为您对initialCapacity
的理解存在问题。就像初始化一个充满了&#39; null&#39;在ArrayList
的初始化过程中,没有任何事情发生。通过设置initialCapacity
n
,您所做的就是让编译器知道它应该为n
个对象分配足够的内存。请注意,即使已经分配了内存,列表的大小仍为0,因为其中没有元素。
关于copy()
。您正尝试将lista
复制到初始容量为lista.size() = 0
的列表中。那里看起来不舒服吗?
这种混淆可能是因为文档根本没有提到size
这个词,但这是关键因素。