This question already has answers here:
Initial size for the ArrayList
(17 answers)
ArrayList initial capacity and IndexOutOfBoundsException [duplicate]
(3 answers)
Closed 2 years ago.
ArrayList<String> Array=new ArrayList<>(5);
Array.add("Ten");
Array.add("Twenty");
Array.add(4,"Fifty");
Array.add("Thirty");
Array.add("Fourty");
System.out.println(Array);
I got the IndexOutOfBoundsException exception when I run this code. Can anyone explain the reason why I am getting this error?
I think this is caused by your misunderstanding of the first argument to the ArrayList constructor. It is not the initial size you are providing, but the capacity.
The ArrayList class works with both a size and capacity. The size is the actual number of added elements within the list. The capacity, however, is the size of the internal array of ArrayList where the actual elements are stored. If enough elements are added, the capacity is increased by copying all elements of the current internal array to a new array with double the size of the current one. This is done because otherwise you have to expand the internal array each time an element is added. That would seriously impact performance.
The single-argument constructor accepts the initial capacity, and not the size. It's common not to specify the capacity, because the capacity is initialized to a sensible default. This constructor, however, exists mainly for performance reasons: if it is known that the number of elements will become very large, one could set the capacity through that constructor, so the ArrayList does not have to resize a lot of times.
You are trying to add "Fifty" at index 4, which is not available because the size of ArrayList is 2 at that point of execution.
Array.add(4,"Fifty"); Adding "Fifty" at index 4
From the void java.util.ArrayList.add(int index, Object element) method declaration :
Throws: IndexOutOfBoundsException - if the index is out of range(index < 0 || index > size())
So you cant add to index number 4 because there is not one at the time the method is called
If you check out the docs, it clearly mentions that:
Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())
At the point of execution, your list size will be 2 and 4 > size i.e 2. Hence, this exception will be thrown.
You can check out the same discussion in Stack Overflow as well.
Your code declares the capacity of your ArrayList, not its actual size. So you can add elements, but adding to position 4 fails because that position doesn't yet exist.
You can check that by looking at the size of your array as you add elements:
System.out.println(array.size());
Adding a value increases your array's size by 1. But if your array's size is only 2, you'll get an error if you try adding a value to position 4.
Depending on your end goal, you could add a couple blank values in order to initialize those positions, then add to position 4:
ArrayList<String> array = new ArrayList<>(5);
Then you can do your adds:
array.add("Ten");
array.add("Twenty");
array.add("");
array.add("");
array.add(4,"Fifty");
array.add("Thirty");
array.add("Fourty");
System.out.println(array);
Related
So let say I have an array of size 10 with index range from 0 to 9.
I add a bunch of elements in and stop adding at index 6. So with array.length, I can know that the size of the array is 10, but how do I find which index contain the last value and after that is empty? Am I suppose to do a loop and stop at index == null?
I mimic an arraylist by create a dynamic array that grow when the size is full.
Arg, forgot to tell you guys, if the array is int, then the empty slots will be 0?
Use java.util.ArrayList. There you no need to think about index and it is resizable-array implementation.
At the time of array creation by default all values are null so if you do not insert any value at any index (may be at end or beginning or middle of array) it would be just null. So you should put null check to verify.
Since this is you assignment a trick is to add a variable to follow the number of elements added.
So you can have a public int size = 0 variable and change you add and remove operations to increase and decrease this variable whenever you add or remove an element.
Then in you add method you can have a simple check to see if you need to expand the array
if (size == array.length)
expandArray
This question already has answers here:
Distinction between the capacity of an array list and the size of an array
(7 answers)
In Java 8, why is the default capacity of ArrayList now zero?
(6 answers)
Closed 5 years ago.
As per the Java API the default capacity for a java.util.ArrayList is 10.
public ArrayList()
Constructs an empty list with an initial capacity of ten.
I created a list without specifying the initial capacity as below and found that the initial capacity is 0 for the list.
ArrayList<String> list = new ArrayList<String>();
ArrayList<String> list50 = new ArrayList<String>(50);
list.add("1");
list50.add("2");
System.out.println(list.size());
I know i am making some silly mistake in interpretation, please correct me.
The initial capacity of a newly instantiated ArrayList is 0 - for performance reasons, an empty ArrayList uses a shared default array of size 0, so that if no new items are added to the list, you don't pay for allocating a new array that is never used.
Once the first item is added, the DEFAULT_CAPACITY (which is 10) is then used, i.e. the ArrayList creates a new array with size 10, which will then hold the first item (and has 9 additional, empty slots).
So I think you indeed used a slightly mistaken interpretation of the documentation.
The initial capacity is 0, and is then increased to 10 upon adding the first item, in order to avoid immediate reallocation for adding the next subsequent 9 items.
size and capacity are not the same...
every time you call add, ArrayList invoke ensureCapacityInternal, there you can find DEFAULT_CAPACITY which is 10 as you pointed....
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
so this statement
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
increase the capacity to 10 after the 1st insertion
So let say I have an array of size 10 with index range from 0 to 9.
I add a bunch of elements in and stop adding at index 6. So with array.length, I can know that the size of the array is 10, but how do I find which index contain the last value and after that is empty? Am I suppose to do a loop and stop at index == null?
I mimic an arraylist by create a dynamic array that grow when the size is full.
Arg, forgot to tell you guys, if the array is int, then the empty slots will be 0?
Use java.util.ArrayList. There you no need to think about index and it is resizable-array implementation.
At the time of array creation by default all values are null so if you do not insert any value at any index (may be at end or beginning or middle of array) it would be just null. So you should put null check to verify.
Since this is you assignment a trick is to add a variable to follow the number of elements added.
So you can have a public int size = 0 variable and change you add and remove operations to increase and decrease this variable whenever you add or remove an element.
Then in you add method you can have a simple check to see if you need to expand the array
if (size == array.length)
expandArray
According to the docs you can insert objects an any position in a List:
The user of this interface has precise control over where in the list each element is inserted.
(source: http://download.oracle.com/javase/6/docs/api/java/util/List.html)
But the following program fails with an IndexOutOfBoundsException:
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
ArrayList<String> myList = new ArrayList<String>();
myList.add(0, "derp");
myList.add(2, "herp");
for (String s : myList) {
System.out.println("Le string: " + s);
}
}
}
It doesn't help setting initial capacity explicitly, either (which makes some sense since the default value is 10).
Why can't I insert objects at any position as long as its index is lower than the capacity? Is the size always equal to the number of inserted elements?
You can insert an object at any valid position. Take a close look at the Javadoc for add(int, E):
Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())
In other words, inserting an element always increases the size of the list by 1. You can insert at either end, or in the middle... but you can't insert past the end.
The capacity of an ArrayList is effectively an implementation detail - it controls when the backing array needs to be replaced by a larger one to cope with more elements. The size of a list is the important part here - a list with capacity 100 but size 5 is still only a list of 5 elements, and so inserting at position 67 into such a list would make no sense.
List capacity is not the same as its size.
The capacity is a property of array backed lists (such ArrayList or Vector), and it is the allocated size of the backing array (that is, the maximum number of items that you could put before needing to grow the structure).
The size, as you say, is the number of elements present in the list.
Then, why wouldn't you be able to insert an element wherever you want as long as there is space for it? Simple, because the List interface does not specify how the object is backed, and you couldn't do it in something like a LinkedList; so the homogeneous (and correct) behaviour is to throw an exception when that happens.
So you have two options:
Initialize the list properly by adding a default values up to your desired size.
If null is a sensible default value for you, you can use an array directly.
myList.add(2, "herp") should be myList.add(1, "herp")
As increases the size of List is by 1,not 2.
ArrayList has two members: capacity and size
capacity is the length of the underlying array, size is the length of the array the ArrayList represents
so you have to add data in the list, so that the ArrayList itself gains the size where you want to insert data
The size of the list is Always equal to the number of the inserted elements
Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())
javadoc
First myList.add(0, "herp") will be inserted then it will check for size. Then, size is 1 but you are inserting at position 2.
if I create a new arraylist of size 5...
Player P;
ArrayList<Player> orderedPlayers = new ArrayList<Player>(5);
and then I try to add to the middle of that arraylist...
orderedPlayers.add(2, P);
I get an indexoutofbounds... I also get indexoutofbounds if I use set instead of add...
orderedPlayers.set(2, P);
in fact the only way I can add P to the arraylist is if I use the 0 index...
orderedPlayers.add(0, P);
and also for some strange reason when I do that my debugger in eclipse sees that element added to the 4th index of orderedPlayers instead of the 0th... is ArrayList buggy or am I completely missing something? how would I add to the middle of a null ArrayList?
The 5 is the initial capacity, not the actual size. You can't add to the middle of an empty array list.
Here is probably what you want to do in order to initialize orderedPlayers:
ArrayList<Player> orderedPlayers =
new ArrayList<Player>(Collections.nCopies( 5, null ));
Then you have a list with 5 null elements, at this point you can insert in the middle of it.
When you create an ArrayList with a number in parameter, this number will be used to set the initial capacity. That way the List won't need to create a new array for "every" call to add(). If you can tell that your List will contain 100 elements, you can use new ArrayList(100). That doesn't mean that the 100 elements exists or are accessible.
Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.
An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.
ArrayLists are dynamic structures... if you want to be able to add stuff at specific locations, you might have to use an array instead.
you may initialize your array list by NULL objects in a loop.
or even if the size is fixed. then use Array instead of List.
You seem to be under the mistaken impression that when you write new ArrayList<Player>(5), you're getting something similar to a 5-element array. You aren't. You're getting an empty list that happens to be backed by an internal array that can initially hold up to 5 elements. The list itself, however, has no elements at all.
Lists are dynamic and grow and shrink as elements are added to them and removed from them. You start out with 0 elements. If you then add 5 players, the list will have 5 elements. If you just use the normal add(T) method with no index, you'll end up with the elements in the order they were added.
By constructing an ArrayList with an initial capacity ArrayList(int initialCapacity), you are indicating roughly how large the list can get before Java will increase its size.
You are not allocating slots, as in an array. The ArrayList's size is based on the number of elements in the list, and you cannot insert or set a value to an index greater than its size.