Difference between implicit and explicit declarations of size ArrayList?

what is the difference between the following ads:

List list1 = new ArrayList(); List list2 = new ArrayList(10); 

By default it is allocated with 10. But is there a difference? Can I add the 11th element to list2 on list2.add("something") ?

+6
source share
6 answers

Here is the source code for the first example

 public ArrayList() { this(10); } 

So there is no difference. Since the initial capacity is 10 , regardless of whether you pass 10 or not, it is initialized with a capacity of 10.

Is it possible to add the 11th element to list2 from list2.add ("something")?

Of course, the initial capacity is not the final capacity. As you keep adding more than 10, the size of the list is increasing.

If you want to have a container with a fixed size, use Array or java.util.Collections.unmodifiableList()

It is worth reading about this change in Java 8: In Java 8, why is the default ArrayList capacity equal to zero?

In short, providing the initial capacity usually does not change any size gaps.

+6
source

You can always add items to the list. However, the original array used by the ArrayList is initialized with either the default size of 10 or the size that you specify when initializing the ArrayList. This means that if, for example, you add the 11th element, the size of the array must be increased, which is done by copying the contents of the array into a new, larger instance of the array. This, of course, takes time depending on the size of the list / array. Therefore, if you already know that your list will contain thousands of elements, it is faster if you already initialize the list with such an approximate size.

+4
source

ArrayList in Java are self-developing and will be resized, if necessary, to add additional elements. The size parameter in the constructor is used only for the initial size of the internal array and is a kind of optimization when you know exactly what you are going to use for the array.

Specifying this initial capacity is often a premature optimization, but if you really need an ArrayList of 10 elements, you should specify it explicitly and not assume that the default size is 10. Although this was indeed the default behavior (before JDK 7, IIRC) , you should not rely on it - JDK 8 (marked with java-1.8.0-openjdk-1.8.0.101-1.b14.fc24.x86_64 , which I installed) creates an empty ArrayList by default.

+4
source

Other answers explained very well, but only to take into account everything in JDK 1.7.0_95:

 /** * Constructs a new {@code ArrayList} instance with zero initial capacity. */ public ArrayList() { array = EmptyArray.OBJECT; } /** * Constructs a new instance of {@code ArrayList} with the specified * initial capacity. * * @param capacity * the initial capacity of this {@code ArrayList}. */ public ArrayList(int capacity) { if (capacity < 0) { throw new IllegalArgumentException("capacity < 0: " + capacity); } array = (capacity == 0 ? EmptyArray.OBJECT : new Object[capacity]); } 

As a comment is mentioned, a non-argument constructor initializes an ArrayList with zero initial capacity.

And even more interesting here is a variable (with a comment) that provides a lot of information on its own:

 /** * The minimum amount by which the capacity of an ArrayList will increase. * This tuning parameter controls a time-space tradeoff. This value (12) * gives empirically good results and is arguably consistent with the * RI specified default initial capacity of 10: instead of 10, we start * with 0 (sans allocation) and jump to 12. */ private static final int MIN_CAPACITY_INCREMENT = 12; 
+2
source

You have just chosen the perfect example. Both actually do the same as new ArrayList() calls this(10) ;) But internally it will define a storage array with size 10. The ArrayList#size method, on the other hand, simply returns the size variable, which will only be after adding and removing items. This variable is also the main cause of IOOB Exceptions. Therefore, you cannot do this.

If you check the ArrayList code, you will notice that the ArrayList # add method will call ArrayList # rangeCheck . Range checking actually just takes care of the size variable, not the force length of the array containing the data for the List .

Because of this, you still cannot insert data into index 5 , for example. The internal length of the data array at this point will be 10 , but since you have not added anything to your List , the size variable will still be 0 , and you will get the correct IndexOutOfBoundsException when you try to do this.

just try calling list.size() after initializing List with any size, and you will notice that the returned size will be 0 .

+1
source

The initialization of ArrayList has been optimized since the JDK 1.7 40 was updated, and there is a good explanation of two different types of behavior at this link java-optimization-empty-arraylist-and-Hashmap-cost-less-memory-jdk-17040-update .

So, before Java 1.7u40 there is no difference, but from this version there is a pretty significant difference.

This difference applies to performance optimization and does not change the contract of List.add(E e) and ArrayList(int initialCapacity) .

0
source

All Articles