ArrayList initial capacity and IndexOutOfBoundsException
What I don't understand is why it doesn't create an "empty" list of size 7, with null values at each index, similar to what would happen if we declared String[] myArray = new String[7].
That would be useful in some cases... and not useful in others. Quite often you have an upper bound of the size of list you're going to create (or at least a guess) but then you populate it... and you don't want to have a list which then has the wrong size... so you'd have to maintain an index while you "set" values, and then set the size afterwards.
I recall learning that ArrayList is Java's implementation of a dynamic array, so I'd expect a similar sort of behavior.
No, it's really not. It's a list which can be resized and uses an array behind the scenes. Try not to think of it as an array.
If I don't actually have space for 7 Strings allocated when I declare new
ArrayList<String>(7)
, what is actually happening?
You do have space for 7 string references. The buffer size (i.e. the capacity) is at least 7, but the logical size of the list is still 0 - you haven't added anything to it. It's like you've got a sheet of paper that's long enough for 7 lines, but you haven't written anything yet.
If you want a prefilled list, you can easily write a method to create one:
public static List<T> createPrefilledList(int size, T item) {
ArrayList<T> list = new ArrayList<T>(size);
for (int i = 0; i < size; i++) {
list.add(item);
}
return list;
}
Java ArrayList IndexOutOfBoundsException despite giving an initial capacity
Here's the source from ArrayList
:
The constructor:
public ArrayList(int initialCapacity)
{
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];
}
You called set(int, E)
:
public E set(int index, E element)
{
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
Set
calls rangeCheck(int)
:
private void rangeCheck(int index)
{
if (index >= size) {
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
}
It may be subtle, but when you called the constructor, despite initializing an Object[]
, you did not initialize size
. Hence, from rangeCheck
, you get the IndexOutOfBoundsException
, since size
is 0. Instead of using set(int, E)
, you can use add(E e)
(adds e
of type E
to the end of the list, in your case: add(1)
) and this won't occur. Or, if it suits you, you could initialize all elements to 0 as suggested in another answer.
Initial size for the ArrayList
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.
ArrayList IndexOutOfBoundsException despite adding within the capacity of the list
it is initialize with 10 elements
No, it isn't. It's initialized with an internal buffer size of 10, but that's largely an implementation detail. The size of the list is still 0, as you can confirm by printing out list.size()
before your add
call.
It's important to differentiate between "amount of space in the buffer ready to accept more elements without copying" and "the size of the list". From the add
documentation:
Throws:
IndexOutOfBoundsException
- if theindex
is out of range (index < 0 || index > size()
)
Here size()
is 0, and 1 > 0
, hence the exception.
You should always check the documentation before assuming that it's the framework (or compiler) that's wrong.
How to fix the issue i want to put item in 1th,2nd or 5th position in my code?
You either need to add enough elements first, e.g.
for (int i = 0; i < 10; i++) {
list.add(null);
}
list.set(1, 555);
list.set(2, 500);
list.set(5, 200);
Note that these are set operations, not add - it's not clear whether you really want to insert or modify.
Or you should potentially use an array instead. For example:
int[] array = new int[10];
array[1] = 555;
array[2] = 500;
array[5] = 200;
In both cases, it's important to understand that indexes are 0-based - so list.set(1, 555)
changes the second element of the list. You'd want list.set(0, 555)
to change the first element. The same applies for arrays.
Set Method of ArrayList throwing IndexOutOfBoundsException
test.set(5, "test");
is the statement that throws this exception, since your ArrayList
is empty (size()
would return 0
if you got to that statement), and you can't set the i'th element if it doesn't already contain a value. You must add at least 6 elements to your ArrayList
in order for test.set(5, "test");
to be valid.
new ArrayList(10)
doesn't create an ArrayList
whose size is 10. It creates an empty ArrayList
whose initial capacity is 10.
ArrayList initialized to a size, but index is out of bounds and size is zero. Why?
The number that you pass to ArrayList
's constructor is the initial capacity of the ArrayList
, not the initial size. The initial size is 0, unless you are passing to the constructor (not the same constructor that takes the capacity parameter) another Collection
used to populate your ArrayList
.
You should never call providers.get(i)
before checking that providers.size() > i
.
P.S.
I see that you have code that initializes the providers
ArrayList
in your analyze
method. However, you initialize a local variable and not the static class member of the same name. This means that getProviders
should actually throw a NullPointerException
and not IndexOutOfBoundsException
(unless you initialize the providers
static member in some code you didn't include).
Try to change your analyze
method to :
public static void analyze(ArrayList<Class<?>> cls, String path){
Package homePkg = Package.getPackage(path.substring(path.lastIndexOf("\\")+1));
providers = new ArrayList<ArrayList<String>>(cls.size());
clients = new ArrayList<ArrayList<String>>(cls.size());
....
Related Topics
Jtable with Titled Rows and Columns
What Does the "Assert" Keyword Do
How to Find Out the Currently Logged-In User in Spring Boot
How to Lower Java Heap When Not in Use
Error Installing Ant: Ant_Home Is Set Incorrectly
Why Converting from Float to Double Changes the Value
Static VS. Dynamic Binding in Java
Is There a 'Block Until Condition Becomes True' Function in Java
Understanding Strange Java Hash Function
How to Call Subclasses' Methods on a Superclass Object
Java Error - Actual and Formal Argument Lists Differ in Length
Mockito:How to Verify Method Was Called on an Object Created Within a Method
Stand-Alone Java Code Formatter/Beautifier/Pretty Printer
Java Enum and Additional Class Files
Invalid Thread Access Error with Java Swt