有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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)

有什么想法吗


共 (3) 个答案

  1. # 1 楼答案

    这确实是Collections.copy()文档的一个问题。它的JDK 8 documentation上写着:

    The destination list must be at least as long as the source list. If it is longer, the remaining elements in the destination list are unaffected.

    这使用了“long”和“longer”这两个术语,它们似乎指的是列表的长度。但是,如果您查看List规范,没有关于长度的定义,但是有关于大小的定义,在ArrayList中,有关于容量的定义。目前还不清楚Collections.copy()是根据列表的大小还是容量来定义的

    事实上,Collections.copy()应该用列表的大小来定义。{}的{a2}已修改为:

    The destination list's size must be greater than or equal to the source list's size. If it is greater, the remaining elements in the destination list are unaffected.

    ArrayList构造函数的arg设置其初始容量,而不是大小大小是列表中当前存在的元素数Collections.copy()要求目标列表的大小大于或等于源列表的大小。这就是为什么当你试图将一个大小为1的列表复制到一个大小为0的列表时,会得到IndexOutOfBoundsException

  2. # 2 楼答案

    如果目标列表太小。我将抛出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);
       }    
    
  3. # 3 楼答案

    我认为你对^{的理解有问题。就像初始化一个用“null”值填充的基元数组一样,在初始化ArrayList过程中不会发生类似的情况。通过设置ninitialCapacity,您所做的就是让编译器知道它应该为n对象分配足够的内存。请注意,即使已经分配了内存,列表的大小仍然是0,因为其中没有元素

    关于copy()。您正在尝试将lista复制到初始容量为lista.size() = 0的列表中。那里好像有什么不对劲吗

    这种混淆可能是因为文档中没有提到size这个词,但这是这里的关键因素