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.
Related
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);
I want to solve this question
1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB
Here is my code
import java.util.ArrayList;
import java.util.List;
public class Solution {
public static String convertToTitle(int n) {
if(n<=0)
return null;
List temp=new ArrayList();
int i=0;
while(n!=0)
{
int residual=0;
residual=n%26;
n=n/26;
temp.add((char)(residual-1+'A'));
i++;
}
char[] temp_final=new char[i];
for(int j=0; j<i-1;j++)
temp_final[j]=(char)(temp.remove(j));
return String.valueOf(temp_final);
}
public static void main(String[] args) {
String test;
test=Solution.convertToTitle(2);
System.out.println(test);
}
}
The result is null. I do not know the reason. When I debug with Eclipse, I find the size of temp shows 1, but in the elementData Object shows 10 elements.The first element is B, the other nine are null. Why is it 10 rather 1? Is it due to this?
This the image of variables when debugging
enter image description here
Why is it 10 rather 1?
Because that is the way that ArrayList works!
An array list stores the list in a backing array (elementData).
When you create an ArrayList with new ArrayList(), the initial backing array size will be 10. (Refer to the source code; e.g. here.)
Why did they do this?
It is all about maintaining this guarantee stated in the javadoc:
"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."
The way that this is achieved is to start the backing array with a reasonable "initial capacity", and grow the array exponentially when it fills up. The exact details vary with Java version.
Hypothetically, the ArrayList class could use a backing array that is the same size as the list size. But that gives terrible performance. Each time you added an element to the list you would need to "grow" the backing array. That entails allocating a new array with size 1 greater than the current size, and then copying the existing elements one at a time to the new array. If you do the math, appending an element to a list of size N involves copying N existing element references ... making the append operation O(N).
An ArrayList is a List implementation using an array to store the elements.
At any point in time, a List has a size(), i.e. the number of elements in the list. For an ArrayList, those elements are stored in a single array with a length that is greater than or equal to the size() (can't very well be less than size(), right?)
The array length is called the capacity of the ArrayList, i.e. the number of elements the ArrayList can handle without having to re-size the array.
The debugger shows the size and the elementData array, but only the first size values of the array are "in the list".
By default, a new ArrayList has an initial capacity of 10. In Java 8, the backing array will be increased in size in 50% chunks when needed, i.e. 10, 15, 22, 33, 49, 73, 109, ...
If you know you're going to add 1000 elements to an ArrayList, you can specify the initial capacity on the constructor. That prevents the need for continually resizing the array as the 1000 elements are added (performance boost).
I am trying to add various items in various positions in an arraylist.
I need to use arraylist as the number of elements to be read is unclear.
while I am adding elements I am getting indexoutofbonds exception.
I understand that If the index is larger than size() I may get the exception.
but since I suppose that the size will be increased when I try to add more elements than size of the arraylist, why I am getting exception? difference between array and arraylist is that arraylist is dynamic and handle size issues? Am I wrong?
An example is as follows. I am using arraylist of arraylists.
arr.add(e1,new ArrayList<Integer>());
in that case e1 may be 1,0,10001,4,540,100000
Isn't arraylist should handle that problem?
What I mean is
I don't want to use that method below. I need spaces between the elements so that other elements can fit into their locations as the program reads the data. I don't want them to be shifted as the add method specified for the above code is taking a position and element. I don't want to add the item to next available position.
arr.add(new ArrayList<Integer>());
Any help will be useful. OR you can ask me to use another data structure in Java that will help my problem.
It'll take care of the dynamically for you if you don't specify the index you want to insert. But if you want to insert at a specific position, you must be sure that:
index >= 0 && index < size()
See the documentation:
Inserts the specified element at the specified position in this list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).
..
Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())
According to the document,
public void add(int index,
E element)
Throws:
IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())
You must ensure that the index is not out of range.
In other word, if you specify index which > size(), ArrayList don't know how to manipulate the elements between size() and the index. Should it construct these elements and add them for you, maybe by default constructor? I think it should be your responsibility. Such as:
if (e1 > arr.size()) {
arr.addAll(Collections.nCopies(e1 - arr.size(), Integer.valueOf(0)));
}
arr.add(e1, new ArrayList<Integer>());
Ok.I figured it out. ArrayList always shifts. You can not leave spaces between elements. That was what I was looking for.
Late answer better than never;)
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
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.