This article is participating in the Java Theme Month – Java Debug Notes Event, see the event link for details
preface
See this question, at a glance, such a simple question, why asked. In fact, on second thought, yes, this is still a very confusing question. For starters, this is really easy to get lost in. Many people don’t understand.
So, let’s take a look at this problem and make an in-depth dissection of it!
Problem of repetition
Define a collection with an initial size of 10
ArrayList<Integer> arr=new ArrayList<Integer>(10);
Add elements using the collection method
Arr. Add (5, 10)
So let’s see what happens
Where there is confusion, why would they report crossing the line? We have already initialized the collection size to 10, add method, add index to 5, less than 10.
It is estimated that beginners have been overwhelmed, so let’s take a detailed look at what is going on.
Problem resolution
So first of all, let’s look at the collection add method, how is it defined
/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
Copy the code
Method, which does provide two arguments, the index location, and the element value.
By looking at the comments, we can see that the specified element is inserted at the specified position in this list. Moves the element currently in that position (if any) and any subsequent elements right (add one to its index).
/**
* A version of rangeCheck used by add and addAll.
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
Copy the code
Observation method rangeCheckForAdd
As we can see, this method evaluates the comparison between index and size
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
Copy the code
So, when we see the previous exception screenshot, the Size is 0, that’s why it came, we seem to have initialized the Size.
The problem, it seems, is initialization. So let’s see what we’re doing when we customize collections.
/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); }}Copy the code
InitialCapacity = initialCapacity; initialCapacity = initialCapacity;
The problem is clear. We have confused the concepts of Size and Capacity.
The problem summary
Size is the number of elements that the collection contains
Capacity defines the number of elements that a collection can contain
Beginners, need to observe the implementation of the source code more carefully.