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.
Related
So, I was reading my textbook about linked lists. So if it isn't a special case if something is inserted at the end of a linked list, is it a special case, by way of contrast if an element is inserted at the end of an array? What is the reason behind the answer. Why? Why isn't it a special case when inserted at the end of a link list and why is/isn't a special case at the end of an array? What about for ArrayLists?
It is also not a special case for Array (if we are not talking about exceeding bounds of Array). But for ArrayList it could be a special case, because ArrayList has a capacity and if it is exceded ArrayList needs to be resized in order to make sure that it has space for inserted element.
Arrays have a fixed size that you give at initialization (This part is important because array elements are stored at consecutive memory addresses). Hence, you cannot append an element to an array without creating a new array.
int[] myArray = new int[10];
myArray.append(42); //Where should it be stored? It would not make sense.
For lists, it depends on the list implementation. The LinkedList consists of several Node connected to each other. Hence, adding an element to the end of the list is equivalent to connecting a new Node to the last Node of the list.
I am researching the difference of arrays and Arraylists. Can anyone clarify if it is possible to add an element to the middle of an array without replacing the existing value (like what the x.add() would to for an arraylist)?
For example: if I had an array of fruit [apples, pears, peaches, nectarines] and I want to insert plums [apples, pears, plums, peaches, nectarines]. Would this be possible and how would it be done?
An array size is fixed, so normally it's complicated to add an element into an array.
But in special cases it is possible:
It is only possible if the array is not yet fully filled.
Like [apples, pears, peaches, nectarines, NULL, NULL]
inserting is then possible if the current size, which you have to record on a separate place, is smaller than the array size.
Inserting then works using System.arraycopy(), where you first move all elements at inserting position and above to one position to the right. Then you add the new element.
The result would be [apples, pears, plums, peaches, nectarines, NULL]
leaving yet place for one more element.
Java's ArrayList uses this technic to provide a dynamic growing array.
In most cases it's better to use ArrayList for this task. In special cases where you have to read millions of elements such a self managed "growing" array is much more memory efficient (e.g 4 times less the memory, because ArrayList always uses Objects while array could also use primitive types, and they need less memory).
Note:
If one reads you question puristic the answer is "No", because you showed a fully filled array. The only chance to add any more element is to allocate a new array with bigger size and copy the old elements and the new one. But then you have a new array. The access to that array must be encapsulated that no one can reference it, except the class which manages the adding and getting values from it. Just look at the source code of ArrayList to get an Idea.
No, it's not possible.
You would need to allocate a new array larger than the existing one and copy everything over to it in the new positions.
No. Arrays have fixed length, and cannot be resized.
An array is a continuous region of memory - so no, you cannot add an element in the middle of an existing array. ArrayList is a List backed by an array. When necessary, ArrayList will allocate a new array and copy existing values into the newly allocate array.
392 public void add(int index, E element) {
393 rangeCheckForAdd(index);
394
395 ensureCapacity(size+1); // Increments modCount!!
396 System.arraycopy(elementData, index, elementData, index + 1,
397 size - index);
398 elementData[index] = element;
399 size++;
400 }
Read the code for ArrayList here.
const array = [1,2,3];
array.splice(2,0,5); \\ (index, number of items you want to replace, item to be replaced with separated by commas)
console.log(array); \\ [1,5,3]
array2 = [1,2,3];
array2.splice(1,0,4,5);
console.log(array2); \\ [1, 4, 5, 2, 3]
Hope this helps the JS Devs
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.
Suppose there are 10 elements in ArrayList and if i have deleted 2 elements from the middle , so the arraylist will contain 8 elements , but will the capacity be 10 or reduced to 8 at that time.
The API states :
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.
and you can always test this empirically in your debugger. After removing two elements, look at the array that backs the ArrayList, and see what it's size is. Most likely, it's 10.
The behaviour depends on the implementation of the ArrayList. You can't rely on this kind of implementation details. The only thing you must consider is that the capacity is always greater or equal to the number of elements in your list. If you need the capacity to be exactly the number of elements (because you may want to reduce memory usage), you will have to ask it explicitly with the function trimToSize().
I think it may change because suppose we create new array list by default JVM allocate say 10 continuous locations in memory .if you put 8 or 2 or zero it will be same .
But is you put 15 element then it will increase it to say 20 memory locations .But if you below 10 again it should release that memory and reduce to 10 default size .
This is dynamic allocation .For 1000 element list if you are removing the element and reduce to 2 then it is logical that it must release that memory .It should depend on number of elements removed.
When I learned Java, I was told that the arraylist works this way:
It creates an array with room for 10 elements.
When the 11th element is added, it is created a new list with room for 20 elements, and the 10 elements are copied into the new array. This will repeat as until there are no more elements to add, or to a maximum size.
Is the List in .NET constructed the same way?
You can easily test this by querying a List's Capacity:
var a = new List<string>();
Console.WriteLine(a.Capacity); // Writes 0
a.Add("abc");
Console.WriteLine(a.Capacity); // Writes 4
a.Add("abc");
a.Add("abc");
a.Add("abc");
a.Add("abc");
Console.WriteLine(a.Capacity); // Writes 8
So it doesn't allocate any room at all upon instantiation, but upon first added item. From 8 it grows to 16, 32, etc...
The generic List type doubles its internal array length every time the current array is filled up.
MSDN Link
The details are a bit different (in terms of the default number of elements and how it expands), but essentially it is the same.
I believe that's how it works, yes. I can't find any documentation at the moment that tells you the exact algorithm they use, but there is definitely the concept of Capacity (size of the "internal" array) and Count (the actual number of elements you've added).