Arraylist Initial Capacity and Indexoutofboundsexception

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 the index 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



Leave a reply



Submit