代码之家  ›  专栏  ›  技术社区  ›  Arun Sudhakaran Nagma Firdose

为什么在将元素添加到第(n-1)个索引之前,即使提供了初始容量,我们也不能将元素添加到第n个索引的列表中

  •  0
  • Arun Sudhakaran Nagma Firdose  · 技术社区  · 6 年前

    假设我声明一个 int

    int[] ar = new int[10];
    ar[4] = 8;      
    System.out.println(Arrays.toString(ar)); //works fine
    

    这是因为当我说大小为10时,会为数组分配大量内存空间,每个索引中都保留其类型的初始值。

    但事实并非如此 List

    java.lang.IndexOutOfBoundsException:索引:4,大小:0

    List<Integer> list = new ArrayList<Integer>(10);
    list.add(4, 8); //exception
    

    当然,列表的大小将返回 0 即使给定了初始容量。为什么它不像数组,我认为没有为列表的10个元素分配内存?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Joop Eggen    6 年前

    现在应该很清楚,构造函数上的初始容量只是初始内部阵列的一点内存管理。没有任何语义意义。

    当实际的 size()

    不存在具有初始元素的批量分配。然而,有:

    List<Integer> list = Collections.nCopies(10, Integer.valueOf(0));
    

    新的 Stream 提供动态生成列表的方法。

    你可以做:

    public <T> void add(List<T> list, int i, T obj) {
        while (list.size() < i) {
            list.add(null);
        }
        list.add(i, obj);
    }
    

    但很明显,你会介绍 它既不安全又丑陋, 需要空检查。

        2
  •  8
  •   GhostCat    6 年前

    这就是 JavaDoc add(int index, E element) :

    抛出IndexOutOfBoundsException-如果索引超出范围(索引<0 | |索引>大小()

    这个 是当前存储的元素数,而不是当前值 容量 .

    事实上,你的车有能力以100英里/小时的速度行驶,这并不意味着你可以在1秒内神奇地从0英里/小时行驶到90英里/小时;-)

    换句话说:答案是大小和容量不一样。容量仅仅意味着:“这是该列表在底层阵列需要增长之前可以增长到的大小”。

        3
  •  0
  •   fountainhead    6 年前

    List<Integer> list = new ArrayList<Integer>(10) 这个 10 指定初始值 容量 .

    指定初始容量只是一个问题 事情只有在使用接受初始容量作为参数的特定构造函数时,才能使用该选项。当您使用其他构造函数时,您无法控制初始容量。

    你指定 n N 添加到列表中要尽可能有效——否则,将每个单独的项目添加到列表中可能会导致一些代价高昂的内部重新调整大小并重新复制到重新调整大小的内部区域。

    the API doc says so .

    这是一个答案。但API文档为什么这么说?为什么事情是这样设计的?

    事情就是这样设计的,因为:

    1. 作为一名程序员,您必须跟踪项目的位置, 在所有可能的职位中(全部能力) . 目前,作为一名程序员,您只跟踪项目的位置, 在所有添加的项目中 . 现在,这不是一个好主意吗 编程噩梦 ?