ArrayList 的初始大小

Posted

技术标签:

【中文标题】ArrayList 的初始大小【英文标题】:Initial size for the ArrayList 【发布时间】:2012-02-12 09:11:14 【问题描述】:

您可以通过以下方式设置

ArrayList<Integer> arr=new ArrayList<Integer>(10);

但是,你不能这样做

arr.add(5, 10);

因为它会导致越界异常。

如果无法访问分配的空间,设置初始大小有什么用?

添加函数定义为add(int index, Object element),所以我没有添加到索引10。

【问题讨论】:

实际上,从文档中可以看出,列表至少需要添加 n 个项目才能set/add item n-1. 感知:不知道是不是很明显,但是指定了。必须仔细阅读 JavaDoc。抛出:IndexOutOfBoundsException - 如果索引超出范围 (index = size())。 嗯,构造函数说“构造一个具有指定初始容量的空列表。”,采用空列表的概念,不能有索引 5。但我同意这可能不可见乍一看…… 我认为公平地说,如果您将数组初始化为特定值,您将假设低于该值的索引可用——这是ArrayList。我个人想要一种方法,可以让我设置一个大小,这样我就可以把东西放在特定的索引处。这种方法似乎明显不存在。 什么 numbskull 以这种方式设计了这些系列?!这会强制对具有可变长度元素的结构的并行实例化进行冗余工作(即 ArrayList ,其中每个数组可以具有不同的长度)。如果内存已经分配,​​因此在添加 N 个元素后不需要重新分配列表,那么这些索引应该从一开始就可以直接访问。在 C/C++、C#、Objective C 和 Swift 之后,Oracle 没有人学习过这种模式吗?! 【参考方案1】:

贡献..

List <Destination\> destinations = Collections.nCopies(source.size(), Destination.class.newInstance());

【讨论】:

【参考方案2】:

我在Stream 上的两分钱。我觉得最好用

IntStream.generate(i -> MyClass.contruct())
         .limit(INT_SIZE)
         .collect(Collectors.toList());

可以灵活地放置任何初始值。

【讨论】:

【参考方案3】:

迟到了,但在 Java 8 之后,我个人发现Stream API 的以下方法更简洁,可以替代the accepted answer。

例如,

Arrays.stream(new int[size]).boxed().collect(Collectors.toList())

其中size 是所需的List 大小并且没有the disadvantage mentioned here,List 中的所有元素都被初始化为0

(我进行了快速搜索,但在发布的任何答案中都没有看到 stream - 如果这个答案是多余的,请随时告诉我,我可以将其删除)

【讨论】:

我也可以在旅途中填充它吗?我有一个从数据库中获取的对象列表,我也需要该列表的大小是固定的【参考方案4】:

我遇到了类似的问题,并且只知道 arrayList 是 List 接口的可调整大小的数组实现,我还希望您可以将元素添加到任何点,但至少可以选择定义初始大小。 无论如何,您可以先创建一个数组并将其转换为如下列表:

  int index = 5;
  int size = 10;

  Integer[] array = new Integer[size];
  array[index] = value;
  ...
  List<Integer> list = Arrays.asList(array);

  List<Integer> list = Arrays.asList(new Integer[size]);
  list.set(index, value);

【讨论】:

【参考方案5】:

这可能对某人有所帮助 -

ArrayList<Integer> integerArrayList = new ArrayList<>(Arrays.asList(new Integer[10]));

【讨论】:

【参考方案6】:

如果你想使用 Collections.fill(list, obj);为了用重复的对象填充列表,您可以使用

ArrayList<Integer> arr=new ArrayList<Integer>(Collections.nCopies(10, 0));

该行将 10 乘以 0 复制到您的 ArrayList 中

【讨论】:

【参考方案7】: ArrayList

容量与其大小不同。 大小等于ArrayList(以及任何其他List实现)中包含的元素数。

容量只是用于内部存储ArrayList元素的底层数组的长度,并且总是大于或等于大小的列表。

在列表上调用 set(index, element) 时,index 与列表元素的实际数量 (=size) 相关(在您的代码中为零,因此抛出 AIOOBE),而不是与数组长度(=容量)(这是特定于ArrayList 的实现细节)。

set 方法对所有List 实现都是通用的,例如LinkedList,它实际上不是由数组实现的,而是作为一个链接的条目链。

编辑:你其实用的是add(index, element)方法,不是set(index, element),但是这里的原理是一样的。

【讨论】:

【参考方案8】:

ArrayList myList = new ArrayList(10);

//  myList.add(3, "DDD");
//  myList.add(9, "III");
    myList.add(0, "AAA");
    myList.add(1, "BBB");

    for(String item:myList)
        System.out.println("inside list : "+item);
    

/*声明arraylist的初始容量只是在内部节省移位时间;当我们在内部添加元素时,它会检查容量以增加容量,您可以先在 0 索引处添加元素,然后在 1 处添加元素,依此类推。 */

【讨论】:

【参考方案9】:

如果您想在ArrayList 中添加 10 个项目,您可以尝试:

for (int i = 0; i < 10; i++)
    arr.add(i);

如果您已经声明了一个数组大小变量,您将使用变量 size 而不是数字 '10'

【讨论】:

【参考方案10】:

如果您想要一个具有预定义大小的列表,您也可以使用:

List<Integer> arr = Arrays.asList(new Integer[10]);

【讨论】:

这里有点缺点,结果List 充满了空值。使用 Guava 我们可以使用Ints.asList(new int[10]) 来初始化我们的列表为0s。干净的模式,谢谢你的例子。 问题讨论了 ArrayList。您正在使用列表。没有人观察到这一点???此外,他们对这个 irrelevant 的答案表示赞同!我不会拒绝您的回答,因为我从来没有这样做过。简直……天哪! @Apostolos ArrayListList 接口的实现,Arrays.asList 返回一个ArrayList。我建议你查一下多态性。 这会返回一个固定大小的列表。尝试添加更多元素会抛出 UnsupportedOperationException @dimo414,有时 null 比添加 3rd 方库依赖项更好。【参考方案11】:

如果要添加带索引的元素,可以改为使用数组。

    String [] test = new String[length];
    test[0] = "add";

【讨论】:

OP 最初想使用列表...而不是数组。【参考方案12】:

虽然您的arraylist 的容量为10,但真正的列表在这里没有元素。 add 方法用于将元素插入到实际列表中。因为它没有元素,所以不能在索引 5 处插入元素。

【讨论】:

【参考方案13】:

您将数组列表的大小与其容量混淆了:

大小是列表中元素的数量; 容量是列表在不重新分配其内部结构的情况下可以容纳多少元素。

当您调用new ArrayList&lt;Integer&gt;(10) 时,您正在设置列表的初始容量,而不是其大小。换句话说,当以这种方式构造时,数组列表的生命开始时是空的。

向数组列表添加十个元素的一种方法是使用循环:

for (int i = 0; i < 10; i++) 
  arr.add(0);

完成此操作后,您现在可以修改索引 0..9 处的元素。

【讨论】:

+1:较短的循环是while(arr.size() &lt; 10) arr.add(0); 可以说,大小至少需要为10。例如所以你可以使用arr.set(9, n); +1:很好的回应,如果可以的话,我会给 +10。从 api 来看,为什么不能在单个构造函数调用中同时设置初始大小和初始容量的原因并不明显。您必须通读 api 并说“哦,我猜 ArrayList 没有方法或构造函数来做到这一点” @PeterLawrey 您的代码可能更短,但每次循环迭代包含两个方法调用,而不仅仅是一个。 @neuralmer 我希望 size() 和 add() 被内联,因此在运行时不会发生实际的方法调用。【参考方案14】:

我想你的问题的确切答案是:

在 ArrayList 上设置初始大小会减少 nr。内部存储器重新分配的次数必须发生。 该列表由数组支持。如果您指定即初始容量 0,则在第一次插入元素时,必须调整内部数组的大小。 如果您大致了解列表将包含多少个元素,则设置初始容量将减少 nr。使用列表时发生的内存重新分配。

【讨论】:

【参考方案15】:

目前您的列表中没有元素,因此当它不存在时,您无法添加到列表的索引 5。您将列表的容量与其当前大小混淆了。

只要打电话:

arr.add(10)

将整数添加到您的 ArrayList

【讨论】:

【参考方案16】:

10 是 AL 的初始容量,而不是大小(为 0)。当您将拥有大量元素时,您应该将初始容量提到一个较高的值,因为它可以避免在您不断添加元素时扩展容量的开销。

【讨论】:

以上是关于ArrayList 的初始大小的主要内容,如果未能解决你的问题,请参考以下文章

奇怪,为什么ArrayList初始化容量大小为10?

奇怪,为什么ArrayList初始化容量大小为10?

Java中ArrayList的初始容量和容量分配

ArrayList,HashMap,LinkedList 初始化大小和 扩容机制

ArrayList扩容源码分析

ArrayList的简单实现