简体   繁体   中英

ArrayList index out of bounds

Why java.lang.IndexOutOfBoundsException is raised in this example, if the size of ArrayList has been predefined? How to solve this problem?

int size = 2:
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size);
Integer[] value1 = {1,2,3};
Integer[] value2 = {1,2};
nums.add(1,value1); // java.lang.IndexOutOfBoundsException
nums.add(0,value2);

You cannot put an item in an ArrayList before the other one is set. If you want to do it you'll have to assign null values to the item on place 0 first.

It will work if you do:

int size = 2:
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size);
Integer[] value1 = {1,2,3};
Integer[] value2 = {1,2};
nums.add(0, null);
nums.add(1,value1);
nums.set(0,value2);

edit/ Replaced add by set to replace the null object

The argument to the ArrayList constructor isn't the size of the list, as your code is assuming; it's the capacity of the underlying storage used by the data structure.

The capacity will grow as required as you add elements to the list. The only reason to specify the initial capacity in the constructor is to pre-allocate a larger capacity if you know you're going to be adding lots of elements. This means that the underlying array doesn't havwe to be resized too often as you add them.

Regardless of what value you specify in the ArrayList constructor, the size of the list is governed solely by what you put into it, so you can't fetch the item with index of 1 until you've added at least 2 elements.

At the time that you add() to the ArrayList , the length of the list is 0. You cannot add past the current end of the List .

I would suggest doing:

nums.add(value2);
nums.add(value1); 

To get the order you appear to want here.

http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(int )

What you specify it's the initial capacity, that's just the initial size that the internal array has and that is increased automatically if need be. It has nothing to do with item position , hence your error. By the way, the default capacity for ArrayLists is 10, so you are actually making it smaller than default.

According to the javadoc , When you write

ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size);

You're not defining the size of nums , you're defining the initial capacity - in this sense, ArrayLists aren't like built-in arrays ( value1 and value2 in your code).

You can try it yourself: print the size of nums after each line (code cleaned up to prevent the IndexOutOfBoundsException.

int size = 2:
ArrayList<Integer[]> nums = new ArrayList<Integer[]>(size);
Integer[] value1 = {1,2,3};
Integer[] value2 = {1,2};
System.out.println(nums.size());
nums.add(value2);
System.out.println(nums.size());
nums.add(value1);
System.out.println(nums.size());

This will print:

0
1
2

In order to get the results you expect I would recommend to use base typed arrays like

Integer[][] nums = new Integer[size][];

and then

Integer[] value1 = {1,2,3};
Integer[] value2 = {1,2};
nums[1] = value1; 
nums[0] = value2;

If you still need an ArrayList just use

new ArrayList<Integer[]>(Arrays.asList(nums));

To get the result you want to have, you have to write

nums.add(0, value1);
nums.add(0, value2);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM