284

You can set the initial size for an ArrayList by doing

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

However, you can't do

arr.add(5, 10);

because it causes an out of bounds exception.

What is the use of setting an initial size if you can't access the space you allocated?

The add function is defined as add(int index, Object element) so I am not adding to index 10.

Null
  • 1,940
  • 9
  • 24
  • 29
Cemre Mengü
  • 15,408
  • 24
  • 97
  • 154
  • 54
    Actually, its not obvious from the docs that a list needs to have at least *n* items added before you can `set/add` item *n-1*. – Perception Jan 17 '12 at 15:17
  • 6
    Perception: I don't know if it is obvious, but it is specified. One has to read JavaDoc carefully.Throws: IndexOutOfBoundsException - if index out of range (index < 0 || index >= size()). – Natix Jan 17 '12 at 15:22
  • 3
    Hm, the constructor says "Constructs an empty list with the specified initial capacity.", taking the notion of an empty list, there cant be an index 5. But i agree that this might not be visible at first glance... – quaylar Jan 17 '12 at 15:24
  • 14
    I think it's also fair to say that if you initialize an array to a specific value, you're going to assume indices lower than that value are available—and this is an `ArrayList`. I, personally, would like a method that would allow me to set a size such that I could put things in at specific indices. This method seems notably absent. – Andrew Wyld May 23 '12 at 17:31
  • 2
    What numbskull designed the collections this way?! This forces redundant work for parallel instantiation of a structure with variable-length elements (i.e. ArrayList where each array can have a different length). If the memory is already allocated so the list doesn't need reallocation after adding N elements, those indices should be directly accessible from the start. Has no one at Oracle learned this pattern after C/C++, C#, Objective C, and Swift?! – patrickjp93 Jan 19 '17 at 01:47
  • 1
    @AndrewWyld `java.util.Vector` has a `setSize(int)` method, but that class is unfortunately synchronized and thus slower than `ArrayList`. – neuralmer Sep 04 '18 at 15:38

16 Answers16

417

You're confusing the size of the array list with its capacity:

  • the size is the number of elements in the list;
  • the capacity is how many elements the list can potentially accommodate without reallocating its internal structures.

When you call new ArrayList<Integer>(10), you are setting the list's initial capacity, not its size. In other words, when constructed in this manner, the array list starts its life empty.

One way to add ten elements to the array list is by using a loop:

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

Having done this, you can now modify elements at indices 0..9.

NPE
  • 438,426
  • 93
  • 887
  • 970
  • 57
    +1: A shorter loop is `while(arr.size() < 10) arr.add(0);` It can be useful to say, the size needs to be at least `10`. e.g. so you can use `arr.set(9, n);` – Peter Lawrey Jan 17 '12 at 16:33
  • 10
    +1: Great response, I would give +10 if I could. It is not immediately obvious from the api why you cannot set BOTH the initial size and the initial capacity in a single constructor call. You sort of have to read through the api and say "Oh, I guess ArrayList does not have a method or constructor to do that" – demongolem May 27 '12 at 20:00
  • 1
    @PeterLawrey Your code might be shorter, but contains two method calls per loop iteration, rather than just one. – neuralmer Sep 04 '18 at 15:35
  • 1
    @neuralmer I would expect size() and add() to be inlined so no actual method call occurs at runtime. – Peter Lawrey Sep 04 '18 at 20:29
124

If you want a list with a predefined size you can also use:

List<Integer> arr = Arrays.asList(new Integer[10]);
dimo414
  • 42,340
  • 17
  • 131
  • 218
Gert Jan Schoneveld
  • 1,357
  • 1
  • 9
  • 4
  • 12
    Slight disadvantage here, the resulting `List` is full of nulls. With Guava we can do `Ints.asList(new int[10])` which will initialize our list with `0`s. Clean pattern though, thanks for the example. – dimo414 Aug 28 '14 at 19:08
  • 1
    The questions talks about ArrayList. You are using List. No one has observed this??? Moreover, they have upvoted this *irrelevant* answer! I don't downvote your answer because I never do. Simply ... Godssake! – Apostolos Feb 18 '18 at 09:16
  • 3
    @Apostolos `ArrayList` is an implementation of the `List` interface and `Arrays.asList` returns an `ArrayList`. I suggest you look up polymorphism. – Liam Potter May 03 '18 at 14:58
  • 1
    This returns a List with a fixed size though. Trying to add more elements throws `UnsupportedOperationException` – Koray Tugay Mar 03 '19 at 16:31
  • We could wrap it with the ArrayList constructor to get an ArrayList: `ArrayList arr = new ArrayList(Arrays.asList(new Integer[10]));` – rogamba Jul 04 '20 at 04:35
  • 1
    @dimo414, sometimes null is better than adding a 3rd party library dependency. – Rohit Gaikwad Oct 04 '20 at 14:58
55

if you want to use Collections.fill(list, obj); in order to fill the list with a repeated object alternatively you can use

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

the line copies 10 times 0 in to your ArrayList

Farzan Skt
  • 783
  • 7
  • 7
21

Capacity of an ArrayList isn't the same as its size. Size is equal to the number of elements contained in the ArrayList (and any other List implementation).

The capacity is just the length of the underlying array which is used to internaly store the elements of the ArrayList, and is always greater or equal to the size of the list.

When calling set(index, element) on the list, the index relates to the actual number of the list elements (=size) (which is zero in your code, therefore the AIOOBE is thrown), not to the array length (=capacity) (which is an implementation detail specific to the ArrayList).

The set method is common to all List implementations, such as LinkedList, which isn't actually implemented by an array, but as a linked chain of entries.

Edit: You actually use the add(index, element) method, not set(index, element), but the principle is the same here.

Natix
  • 13,037
  • 7
  • 49
  • 67
10

If you want to add the elements with index, you could instead use an array.

    String [] test = new String[length];
    test[0] = "add";
user3692587
  • 101
  • 1
  • 2
9

10 is the initial capacity of the AL, not the size (which is 0). You should mention the initial capacity to some high value when you are going to have a lots of elements, because it avoids the overhead of expanding the capacity as you keep adding elements.

Bhesh Gurung
  • 48,464
  • 20
  • 87
  • 139
6

I guess an exact answer to your question would be:

Setting an intial size on an ArrayList reduces the nr. of times internal memory re-allocation has to occur. The list is backed by an array. If you specify i.e. initial capacity 0, already at the first insertion of an element the internal array would have to be resized. If you have an approximate idea of how many elements your list would hold, setting the initial capacity would reduce the nr. of memory re-allocations happening while you use the list.

quaylar
  • 2,489
  • 1
  • 14
  • 28
5

This might help someone -

ArrayList<Integer> integerArrayList = new ArrayList<>(Arrays.asList(new Integer[10]));
Hrishikesh Kadam
  • 29,211
  • 3
  • 19
  • 29
5

Being late to this, but after Java 8, I personally find this following approach with the Stream API more concise and can be an alternative to the accepted answer.

For example,

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

where size is the desired List size and without the disadvantage mentioned here, all elements in the List are initialized as 0.

(I did a quick search and did not see stream in any answers posted - feel free to let me know if this answer is redundant and I can remove it)

H.T. Koo
  • 108
  • 4
  • 9
  • can I populate it on the go too? I have a list of objects I got from database and I need that list to be of fixed size too – Kirill Mar 23 '21 at 14:29
3

Right now there are no elements in your list so you cannot add to index 5 of the list when it does not exist. You are confusing the capacity of the list with its current size.

Just call:

arr.add(10)

to add the Integer to your ArrayList

Hunter McMillen
  • 52,839
  • 21
  • 105
  • 154
1

Although your arraylist has a capacity of 10, the real list has no elements here. The add method is used to insert a element to the real list. Since it has no elements, you can't insert an element to the index of 5.

roll1987
  • 163
  • 1
  • 7
1

If you want to add 10 items to your ArrayList you may try that:

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

If you have already declare an array size variable you would use the variable size instead of number '10'

msrd0
  • 6,403
  • 9
  • 36
  • 64
panther
  • 21
  • 1
1

I faced with the similar issue, and just knowing the arrayList is a resizable-array implementation of the List interface, I also expect you can add element to any point, but at least have the option to define the initial size. Anyway, you can create an array first and convert that to a list like:

  int index = 5;
  int size = 10;

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

or

  List<Integer> list = Arrays.asList(new Integer[size]);
  list.set(index, value);
unk
  • 71
  • 1
  • 3
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);
    }

/*Declare the initial capasity of arraylist is nothing but saving shifting time in internally; when we add the element internally it check the capasity to increase the capasity, you could add the element at 0 index initially then 1 and so on. */

sambhu
  • 111
  • 1
  • 5
0

My two cents on Stream. I think it's better to use

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

with the flexibility to put any initial values.

anch2150
  • 51
  • 6
0

contrib..

List <Destination\> destinations = Collections.nCopies(source.size(), Destination.class.newInstance());
lcssanches
  • 933
  • 12
  • 29