Why does this code throw an IndexOfOutBoundsException - aka, what's up with ensureCapacity()?

StackOverflow https://stackoverflow.com/questions/1644741

  •  10-07-2019
  •  | 
  •  

Question

Consider the following two snippets of code:

int index = 676;
List<String> strings = new ArrayList<String>();
strings.add(index, "foo");

and

int index = 676;
List<String> strings = new ArrayList<String>();
strings.ensureCapacity(index);
strings.add(index, "foo");

In the first case, I'm not surprised to see an IndexOfOutBoundsException. According to the API, add(int index, E element) will throw an IndexOfOutBoundsException "if the index is out of range (index < 0 || index > size())". The size of strings is 0 before any elements have been added, so index will definitely be larger than the ArrayList's size.

However, in the second case, I would expect the call to ensureCapacity to grow strings such that the call to add would correctly insert the string "foo" at index 676 - but it doesn't.

  1. Why not?

  2. What should I do so that add(index, "foo") works for index > strings.size()?

Was it helpful?

Solution

The capacity of the underlying array in an ArrayList is distinct from the higher-level List API methods (add, remove, etc.), and only speaks to the size of the backing array. If you want to allow adding elements beyond the list bounds, you'll need to code that yourself (or find a collection that does it for you) in a utility class, populating nulls, empty objects, or whatever your application expects between the new index and the old size.

OTHER TIPS

ArrayList.ensureCapacity() does not change the actual size of the list (which is returned by size()), but rather reallocate the internal buffer such that it will not need to reallocate the buffer to grow to this size (when you call list.add(object).

/**
 * Increases the capacity of this <tt>ArrayList</tt> instance, if
 * necessary, to ensure that it can hold at least the number of elements
 * specified by the minimum capacity argument.
 */

Taking a wild guess, I think what you're looking for is

Integer index = Integer.valueOf(676);
Map<Integer,String> strings = new HashMap<Integer,String>();
strings.put(index, "foo");

your length is 676, but you have to remember that they are zero based, so in reality, you'd want index -1 would be your max number.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top