Skip to main content

ArrayLists vs LinkedLists

· 10 min read
Sarthak Mohanty
caution

LinkedList is faster than ArrayList while inserting and deleting elements, but it is slow while fetching each element.

  • LinkedList is faster in add and remove compared to ArrayList. ArrayList is faster in get().

Elements to be added or removed are too large, go for LinkedList. Usage of get() is more, go for ArrayList. Again, if you don’t have element access in a large number, go for LinkedList.

  • LinkedList could be used for large lists of data since the total elements vary accordingly. In an ArrayList, the maximum elements in the list will be known, and it can be used for small lists.

  • If you are using retrieval operations frequently, go for ArrayList. Retrieval operation means collecting the data from a data structure, which can be stored, viewed and printed. ArrayList performs shift operations internally, so the insertion of data in the middle or deletion in the middle is complicated. If you are opting these operations, ArrayList won’t be the best. It stores elements in different memory locations, and hence the process of retrieval will be convenient. If you are performing insertion of data in the middle or deletion of data in the middle is relatively easy, hence go for LinkedList. It works best for frequent addition or deletion in the middle. They do not store elements in different memory locations, and therefore, if you are looking for more Retrieval operations, LinkedList is not the best one. In a retrieval operation, the elements should be stored in consecutive memory locations else it won’t be easy.


info
  • ArrayList vs LinkedList in terms of Time Complexity
OperationArrayListLinkedListWinner
get(index)O(1)O(n) for n/4 steps in avgArrayList
add(E)O(1) BUT O(n) in worst caseO(1)Linked List
add(index, E)O(n) for n/2 stepsO(n) for n/4 steps BUT O(1) if index = 0Linked List
remove(index, E)O(n) for n/2 stepsO(n) for n/4 stepsLinked List
Iterator.remove() ListIterator.add()O(n)O(1)Linked List

ArrayListLinkedList
Allows fast read accessRetrieving element takes O(n)
Adding an element require shifting all the later elementso(1) [but traversing takes time]
To add more elements than capacity new array need to be allocated

Detailed difference between ArrayLists & LinkedLists

tip

We are going on an exciting journey of comparing ArrayList and LinkedList in detail.

What is inside?

Let's start with a quick and illustrative overview of how our lists look inside.
On the inside, an ArrayList is a resizable array of objects, where every element has an index.

A LinkedList is a doubly-linked list based on connected nodes. LinkedList stores its head and tail.

A node is a class that has three fields: the element itself, the previous, and the next node.

Now, with these pictures in mind, it's time to think how fast standard operations will work for both of them and why.

First round: ArrayList

The logic of an ArrayList is simple: because internally it's an array, the operations get(int index) and set(int index, E element) will be fast. In other words, the time complexity for access by an index is O(1).

If you use the add(E e) operation, a new element will be added to the end of ArrayList. This would also be fast and take constant time to make, so the complexity would be the same: O(1).

But if you would like to insert an element into the ArrayList by using the add(int index, E element) operation the situation will be different. To put the new element into a specific index the ArrayList needs to move all subsequent elements.

In our example, after the insertion, an element "Array" will have an index of 4 and an element "List!" will have an index of 5. If there are a lot of subsequent elements this operation will be quite long with the time complexity O(n).

Let's take a look at what is really happening inside of Java.

When you want to add a new element to the full ArrayList, firstly, a new array with a bigger size will be created. Then all existing elements will be copied to that new array. And only then your new element will be added. So, the worst time complexity would be O(n).

An ArrayList is a resizable array, so when you fill up its initial size, it becomes bigger and that will happen again and again.

The last operation is remove(int index). When you would like to remove an element all subsequent elements will have to be moved.

Because of moving all subsequent elements, this operation won't be very efficient for a long list, with the time complexity O(n).

Now you know what is happening with ArrayList and it's time to pay some attention to his rival LinkedList.

Final round: LinkedList

A LinkedList is not an array, so it doesn't support fast access by index. But it can reach an element by its index. In order to do this LinkedList decides what will be closer to that index: head or tail. And then going from either head or tail, LinkedList traverses all the elements before it reaches the required one.

fistElement.next.next.next.next.next.next...

Let's start with get(int index) and set(int index, E element) operations.

To get an element "am" with an index 1, LinkedList will start from the head. In our example, LinkedList will need to go only through one link: between element "I" and element "am". But if you have a long LinkedList and the required index is in the middle, these operations get(int index) and set(int index, E element) will take a lot of time. So, in a bad situation, the time complexity would be O(n).

Adding an element to the end of the LinkedList is a fast operation. LinkedList will connect the new element "Hello!" with the last element "List" and will make the element "Hello" the new tail.

So it always takes constant time and the complexity of add(E e) is O(1).

Besides the method add(E e) there are two other methods: addFirst(E e) and addLast(E e). As you can understand from their names, they add the element in the head and in the tail of the LinkedList respectively. Their internal mechanism is absolutely the same as with the method add(E e). And their complexity is also O(1). The method addLast(E e) is the equivalent to the method add(E e). The difference is that the method add(E e) returns boolean and the method addLast(E e) returns void.

And what about the inserting element into the concrete index with the operation add(int index, E element)?

To add an element LinkedList needs to reach the required position and then only change the links of the new element neighbors.

And that's it: connect the new element with the previous and the next element, and the insertion is done. No need to move elements as in the ArrayList.

If you add new elements near the head or tail the time complexity of it would be O(1). In most situations, it's a fast operation. But if your list is a very long one then reaching the element in the middle wouldn't be so fast. So, in a bad situation, the time complexity would be O(n).

The last one is remove(int index) operation. The mechanism is the same, LinkedList needs to reach the element and change the links.

By changing the neighbors' links the unwanted element would be deleted. And again, for most situations, it's a fast operation. But for removing the element from the middle of a very long LinkedList the time complexity would be O(n).

LinkedList has two other useful methods: removeFirst() and removeLast(). For them, LinkedList doesn't need to traverse the elements. It just removes the first or last element and changes the head or tail respectively. The time complexity for both operations is O(1).

And the winner is...

Let's illustrate the main points with a table:

So, there is no absolute winner in our competition. Yes, ArrayList is more popular, but in fact, everything depends on the task you are working on. For all operations, it's impossible to say in advance whether they are fast or take a long time. It depends on what is the size of your list and with which part of it you are working. The most important thing for you to understand is how these operations work. Sometimes it may be difficult to make the right choice, but with this understanding, you will definitely avoid silly mistakes.