ArrayList 的初始大小

Initial size for the ArrayList

提问人:Cemre Mengü 提问时间:1/17/2012 最后编辑:NullCemre Mengü 更新时间:10/6/2023 访问量:655854

问:

您可以通过执行以下操作来设置 ArrayList 的初始大小

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

但是,你不能这样做

arr.add(5, 10);

因为它会导致越界异常。

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

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

Java ArrayList 索引OutofboundsException

评论

57赞 Perception 1/17/2012
实际上,从文档中并不明显,列表需要至少添加 n 个项目,然后才能添加项目 n-1set/add
6赞 Natix 1/17/2012
感知:我不知道是否明显,但它是指定的。必须仔细阅读 JavaDoc。抛出:IndexOutOfBoundsException - 如果索引超出范围(索引< 0 || 索引 >= size())。
3赞 quaylar 1/17/2012
嗯,构造函数说“构造一个具有指定初始容量的空列表”,采用空列表的概念,不能有索引 5。但我同意,乍一看可能看不到......
20赞 Andrew Wyld 5/24/2012
我认为也可以公平地说,如果你将一个数组初始化为一个特定的值,你将假设低于该值的索引是可用的——这是一个 .就我个人而言,我想要一种方法,允许我设置一个大小,以便我可以将内容放入特定的索引中。这种方法似乎明显不存在。ArrayList
4赞 patrickjp93 1/19/2017
什么麻木的头骨以这种方式设计了这些系列?!这强制冗余工作,用于使用可变长度元素(即 ArrayList<String[]>其中每个数组可以具有不同的长度)的结构的并行实例化。如果内存已分配,因此在添加 N 个元素后不需要重新分配列表,则这些索引应该从一开始就可以直接访问。在 C/C++、C#、Objective C 和 Swift 之后,Oracle 没有人学习过这种模式吗?!

答:

9赞 Bhesh Gurung 1/17/2012 #1

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

504赞 NPE 1/17/2012 #2

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

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

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

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

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

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

评论

66赞 Peter Lawrey 1/18/2012
+1:较短的循环是 可以说,大小至少需要 。例如,这样你就可以使用while(arr.size() < 10) arr.add(0);10arr.set(9, n);
12赞 demongolem 5/28/2012
+1:很好的回应,如果可以的话,我会给+10。从 api 中并不能立即看出为什么您不能在单个构造函数调用中同时设置初始大小和初始容量。你必须通读 api 并说“哦,我猜 ArrayList 没有方法或构造函数来做到这一点”
1赞 neuralmer 9/4/2018
@PeterLawrey 您的代码可能更短,但每次循环迭代包含两个方法调用,而不仅仅是一个。
1赞 Peter Lawrey 9/5/2018
@neuralmer我希望 size() 和 add() 是内联的,因此在运行时不会发生实际的方法调用。
3赞 Hunter McMillen 1/17/2012 #3

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

只需致电:

arr.add(10)

将 Integer 添加到 ArrayList 中

24赞 Natix 1/17/2012 #4

的容量与其大小不同。Size 等于 (和任何其他实现) 中包含的元素数。ArrayListArrayListList

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

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

该方法对于所有实现都是通用的,例如 ,它实际上不是由数组实现的,而是作为条目的链接链实现的。setListLinkedList

编辑:您实际上使用了该方法,而不是,但这里的原理是一样的。add(index, element)set(index, element)

6赞 quaylar 1/17/2012 #5

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

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

1赞 roll1987 2/11/2014 #6

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

161赞 Gert Jan Schoneveld 5/11/2014 #7

如果需要具有预定义大小的列表,还可以使用:

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

评论

17赞 dimo414 8/29/2014
这里略有缺点,结果是充满了空值。使用 Guava,我们可以这样做,它将使用 s 初始化我们的列表。干净的模式,谢谢你的例子。ListInts.asList(new int[10])0
1赞 Apostolos 2/18/2018
这些问题涉及 ArrayList<E>。您正在使用 List<E>。没有人观察到这一点???而且,他们已经对这个无关紧要的答案投了赞成票!我不会对你的答案投反对票,因为我从来没有这样做过。上帝之缘!
5赞 Liam Potter 5/3/2018
@Apostolos 是接口的实现,并返回 .我建议你查一下多态性。ArrayListListArrays.asListArrayList
1赞 Koray Tugay 3/4/2019
不过,这将返回一个具有固定大小的 List。尝试添加更多元素抛出UnsupportedOperationException
2赞 Rohit Gaikwad 10/4/2020
@dimo414,有时 null 比添加第三方库依赖项更好。
10赞 user3692587 8/13/2014 #8

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

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

评论

8赞 Stephan 8/7/2016
OP 最初想使用一个列表......不是数组。
1赞 panther 10/12/2014 #9

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

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

如果您已经声明了数组大小变量,则可以使用该变量而不是数字“10”size

0赞 sambhu 3/11/2015 #10

ArrayList myList = 新 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,依此类推。*/

69赞 Farzan.s 4/9/2016 #11

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

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

该行将 10 次 0 复制到 ArrayList 中

7赞 Hrishikesh Kadam 6/14/2018 #12

这可能会对某人有所帮助——

ArrayList<Integer> integerArrayList = new ArrayList<>(Arrays.asList(new Integer[10]));
4赞 unk 10/10/2018 #13

我遇到了类似的问题,并且只知道 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);
6赞 H.T. Koo 2/26/2019 #14

虽然很晚,但在 Java 8 之后,我个人认为以下 API 方法更简洁,可以替代公认的答案Stream

例如

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

其中 是所需的大小,并且没有这里提到的缺点,其中的所有元素都初始化为 。sizeListList0

(我做了一个快速搜索,没有看到任何发布的答案 - 如果这个答案是多余的,我可以删除它,请随时让我知道)stream

评论

0赞 Kirill 3/23/2021
我也可以在旅途中填充它吗?我有一个从数据库获得的对象列表,我也需要该列表的大小是固定的
2赞 anch2150 8/29/2019 #15

我的两分钱.我觉得最好用Stream

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

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

0赞 pattern cutter 11/25/2020 #16

贡献..

List <Destination\> destinations = Collections.nCopies(source.size(), Destination.class.newInstance());
0赞 Wasit Shafi 2/15/2023 #17

我们传递给构造函数的参数是为 N 个元素保留的内存容量,而不是数组列表的大小,即元素的数量,有关更多信息,可以参考官方文档:ArrayList 构造函数

但是,您要实现的目标仍然可以通过在代码中进行少量更改来轻松完成,方法是最初分配具有一些默认值的 N 个元素,而不是使用 use 方法来更新值add()set()

import java.util.*;

class Scratch {
  public static void main(String[] args) {
    int DEFAULT_INT_VALUE = 0;

    // set first 10 elements with default value 0
    List<Integer> arr = new ArrayList<Integer>(Collections.nCopies(10, DEFAULT_INT_VALUE));

    // why to use set(5, 10) instead of add(5, 10)..? simply because add() will insert new element at index 5, which here actually we just to modify the 5 index element in array list
    arr.set(5, 10);

    // output: arr= [0, 0, 0, 0, 0, 10, 0, 0, 0, 0]
    System.out.println("arr= " + arr.toString());
  }
}
0赞 Tajdin Gurdal 10/6/2023 #18

最好的方法是:

EvictingQueue<Integer> ignitionOnOdometer = EvictingQueue.create(size);

评论

0赞 Community 10/9/2023
您的答案可以通过其他支持信息进行改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。