ArrayList的初始大小


257

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

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

但是,你做不到

arr.add(5, 10);

因为它会导致超出范围的异常。

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

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


52
实际上,从文档中并不明显,一个列表需要至少添加n个项目,然后才能设置n-1个set/add项目。
感知2012年

5
知觉:我不知道它是否显而易见,但已明确。抛出:IndexOutOfBoundsException-如果索引超出范围(索引<0 ||索引> = size())。
Natix 2012年

3
嗯,构造函数说:“以指定的初始容量构造一个空列表。”,采用空列表的概念,不能有索引5。但是我同意乍一看这可能不可见...
quaylar

12
我认为还可以说,如果将数组初始化为特定值,则将假定有低于该值的索引可用-这是一个ArrayList。我个人希望使用一种方法来设置大小,以便可以将其放入特定的索引中。似乎没有这种方法。
安德鲁·怀尔德

1
是什么numbskull这样设计收藏的?这迫使冗余工作用于具有可变长度元素的结构的并行实例化(即ArrayList <String []>,其中每个数组可以具有不同的长度)。如果已经分配了内存,则在添加N个元素后不需要重新分配列表,则应该从头开始直接访问这些索引。在C / C ++,C#,Objective C和Swift之后,Oracle中没有人知道这种模式吗?
patrickjp93

Answers:


387

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

  • 大小是在列表中的元素的数目;
  • 容量是多少元素列表可以潜在地容纳而不重新分配其内部结构。

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

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

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

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


51
+1:循环更短while(arr.size() < 10) arr.add(0);可以说,大小至少应为10。例如,因此您可以使用arr.set(9, n);
Peter Lawrey 2012年

10
+1:反应很好,如果可以的话,我会给+10。从api中不能立即看出为什么不能在单个构造函数调用中同时设置初始大小和初始容量。您有点必须阅读api并说“哦,我想ArrayList没有方法或构造函数可以做到这一点”
demongolem 2012年

@PeterLawrey您的代码可能更短,但每个循环迭代包含两个方法调用,而不仅仅是一个。
Neuromer

@neuralmer我希望内联size()和add(),因此在运行时不会发生实际的方法调用。
彼得·劳瑞

109

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

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

11
这里的缺点List是,结果充满了空值。使用番石榴,我们可以做到Ints.asList(new int[10]),将使用0s 初始化列表。干净的模式,但感谢示例。
dimo414 2014年

1
这些问题涉及ArrayList <E>。您正在使用List <E>。没有人观察到这个???而且,他们还投票反对了这个无关紧要的答案!我不会拒绝您的回答,因为我从不这样做。简直……天哪!
Apostolos

3
@Apostolos ArrayList是该List接口的实现,并Arrays.asList返回ArrayList。我建议您查找多态性。
利亚姆·波特

但是,这将返回一个具有固定大小的列表。试图添加更多元素UnsupportedOperationException
Koray Tugay

47

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

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

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


20

容量ArrayList是不一样的大小大小等于ArrayList(和任何其他List实现)中包含的元素数。

容量是其用于存储internaly的元素的底层阵列的只是长度ArrayList,并且是始终大于或等于大小列表。

调用set(index, element)列表时,index关联与列表元素的实际数量(= size)(在代码中为零,因此AIOOBE抛出),而不与数组长度(= capacity)(具体实现细节有关)到ArrayList)。

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

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


10

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

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

5
OP最初希望使用列表,而不是数组。
斯蒂芬,

9

10是AL的初始容量,而不是大小(为0)。当您要包含很多元素时,应该提到初始容量要高一些,因为这样可以避免在不断添加元素时扩展容量的开销。


6

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

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



3

迟到了,但是在Java 8之后,我个人发现以下使用StreamAPI的方法更加简洁,可以替代公认的答案

例如,

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

size所需的List大小在哪里,并且没有这里提到的缺点,中的所有元素List都初始化为0

(我进行了快速搜索,但未stream在张贴的答案中看到任何内容-请随时让我知道此答案是否多余,可以将其删除)


1

现在,列表中没有元素,因此如果列表的索引5不存在,则无法添加。您将列表的容量与其当前大小相混淆。

只需致电:

arr.add(10)

将整数添加到您的ArrayList


1

尽管arraylist的容量为10,但实际列表此处没有元素。add方法用于将元素插入到实际列表中。由于它没有元素,因此无法将元素插入索引为5的位置。


1

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

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

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


1

我遇到了类似的问题,仅知道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);

0

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处添加元素,依此类推。* /


0

我的两分钱Stream。我认为最好用

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.