Reputation: 398
I read THIS and
And understood that LinkedList add(E element) is O(1) and ArrayList add(E element) is O(1) amortized, but O(n) worst-case since the array must be resized and copied
But, when i try to check it
public class ArrayListVSLinkeedList {
public ArrayListVSLinkeedList() {
final int COUNTER = 15000000;
List<Integer> arrayList = new ArrayList<Integer>();
long tStart_add = System.currentTimeMillis();
for (int i = 0; i < COUNTER; i++) {
arrayList.add(i);
}
long tEnd_add = System.currentTimeMillis();
long tDelta_add = tEnd_add - tStart_add;
System.out.println("Adding to ArrayList: " +tDelta_add);
List<Integer> linkedList = new LinkedList<Integer>();
tStart_add = System.currentTimeMillis();
for (int i = 0; i < COUNTER; i++) {
linkedList.add(i);
}
tEnd_add = System.currentTimeMillis();
tDelta_add = tEnd_add - tStart_add;
System.out.println("Adding to LinkedList: " +tDelta_add);
}
public static void main(String[] args) {
new ArrayListVSLinkeedList();
}
}
I received at output:
Adding to ArrayList: 9122
Adding to LinkedList: 19859
I know, this is not real benchmark, but... Finally, adding element to the end of ArrayList is faster then to LinkedList. Why this happens?
Upvotes: 4
Views: 532
Reputation: 20608
This is simply due to the implementation.
Have a look at the implementation of ArrayList.add
:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
An ArrayList
internally holds an array whose elements are references to the objects you are managing with that list. The method ensureCapacityInternal
simply checks whether this internal array is still large enough to add another element.
If so, the element is added and the method returns. This is extremely fast (and - btw - is O(1)).
If the array is already full, then a new array with a larger size will be allocated, every reference will be copied from the old array to the new array. Afterwards, the element will be added. This - of course - is O(n). But this happens seldom, and because of the resizing strategy (doubling the size) it will become more and more seldom.
On the other hand, let's have a look at the implementation of LinkedList.add
:
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
Here you see that for each added element a new node object must be created which then is added as the last element. No resizing is done, so that method is always O(1), but the creation of a node object takes more time than simply storing a reference.
Upvotes: 6
Reputation: 4033
Well, it depends how much memory you have on the machine, think that the ArrayList you are creating is already in memory and the LinkedList has to allocate new memory.. Try to run it the other way around and see the results.
Better yet - try to run them in separate methods and see a fair result.
Upvotes: 0