3645

I've always been one to simply use:

List<String> names = new ArrayList<>();

I use the interface as the type name forportability, so that when I ask questions such as this, I can rework my code.

When shouldLinkedList be used overArrayList and vice-versa?

Simeon Leyzerzon's user avatar
Simeon Leyzerzon
19.1k11 gold badges60 silver badges94 bronze badges
askedNov 27, 2008 at 1:36
sdellysse's user avatar
4

35 Answers35

3893

SummaryArrayList withArrayDeque are preferable inmany more use-cases thanLinkedList. If you're not sure — just start withArrayList.


TLDR, inArrayList accessing an element takes constant time [O(1)] and adding an element takes O(n) time [worst case]. InLinkedList inserting an element takes O(n) time and accessing also takes O(n) time butLinkedList uses more memory thanArrayList.

LinkedList andArrayList are two different implementations of theList interface.LinkedList implements it with a doubly-linked list.ArrayList implements it with a dynamically re-sizing array.

As with standard linked list and array operations, the various methods will have different algorithmic runtimes.

ForLinkedList<E>

  • get(int index) isO(n) (withn/4 steps on average), butO(1) whenindex = 0 orindex = list.size() - 1 (in this case, you can also usegetFirst() andgetLast()).One of the main benefits ofLinkedList<E>
  • add(int index, E element) isO(n) (withn/4 steps on average), butO(1) whenindex = 0 orindex = list.size() - 1 (in this case, you can also useaddFirst() andaddLast()/add()).One of the main benefits ofLinkedList<E>
  • remove(int index) isO(n) (withn/4 steps on average), butO(1) whenindex = 0 orindex = list.size() - 1 (in this case, you can also useremoveFirst() andremoveLast()).One of the main benefits ofLinkedList<E>
  • Iterator.remove() isO(1).One of the main benefits ofLinkedList<E>
  • ListIterator.add(E element) isO(1).One of the main benefits ofLinkedList<E>

Note: Many of the operations needn/4 steps on average,constant number of steps in the best case (e.g. index = 0), andn/2 steps in worst case (middle of list)

ForArrayList<E>

  • get(int index) isO(1).Main benefit ofArrayList<E>
  • add(E element) isO(1) amortized, butO(n) worst-case since the array must be resized and copied
  • add(int index, E element) isO(n) (withn/2 steps on average)
  • remove(int index) isO(n) (withn/2 steps on average)
  • Iterator.remove() isO(n) (withn/2 steps on average)
  • ListIterator.add(E element) isO(n) (withn/2 steps on average)

Note: Many of the operations needn/2 steps on average,constant number of steps in the best case (end of list),n steps in the worst case (start of list)

LinkedList<E> allows for constant-time insertions or removalsusing iterators, but only sequential access of elements. In other words, you can walk the list forwards or backwards, but finding a position in the list takes time proportional to the size of the list. Javadoc says"operations that index into the list will traverse the list from the beginning or the end, whichever is closer", so those methods areO(n) (n/4 steps) on average, thoughO(1) forindex = 0.

ArrayList<E>, on the other hand, allow fast random read access, so you can grab any element in constant time. But adding or removing from anywhere but the end requires shifting all the latter elements over, either to make an opening or fill the gap. Also, if you add more elements than the capacity of the underlying array, a new array (1.5 times the size) is allocated, and the old array is copied to the new one, so adding to anArrayList isO(n) in the worst case but constant on average.

So depending on the operations you intend to do, you should choose the implementations accordingly. Iterating over either kind of List is practically equally cheap. (Iterating over anArrayList is technically faster, but unless you're doing something really performance-sensitive, you shouldn't worry about this -- they're both constants.)

The main benefits of using aLinkedList arise when you re-use existing iterators to insert and remove elements. These operations can then be done inO(1) by changing the list locally only. In an array list, the remainder of the array needs to bemoved (i.e. copied). On the other side, seeking in aLinkedList means following the links inO(n) (n/2 steps) for worst case, whereas in anArrayList the desired position can be computed mathematically and accessed inO(1).

Another benefit of using aLinkedList arises when you add or remove from the head of the list, since those operations areO(1), while they areO(n) forArrayList. Note thatArrayDeque may be a good alternative toLinkedList for adding and removing from the head, but it is not aList.

Also, if you have large lists, keep in mind that memory usage is also different. Each element of aLinkedList has more overhead since pointers to the next and previous elements are also stored.ArrayLists don't have this overhead. However,ArrayLists take up as much memory as is allocated for the capacity, regardless of whether elements have actually been added.

The default initial capacity of anArrayList is pretty small (10 from Java 1.4 - 1.8). But since the underlying implementation is an array, the array must be resized if you add a lot of elements. To avoid the high cost of resizing when you know you're going to add a lot of elements, construct theArrayList with a higher initial capacity.

If the data structures perspective is used to understand the two structures, a LinkedList is basically a sequential data structure which contains a head Node. The Node is a wrapper for two components : a value of type T [accepted through generics] and another reference to the Node linked to it. So, we can assert it is a recursive data structure (a Node contains another Node which has another Node and so on...). Addition of elements takes linear time in LinkedList as stated above.

An ArrayList is a growable array. It is just like a regular array. Under the hood, when an element is added, and the ArrayList is already full to capacity, it creates another array with a size which is greater than previous size. The elements are then copied from previous array to new one and the elements that are to be added are also placed at the specified indices.

Sign up to request clarification or add additional context in comments.

16 Comments

One thing many people forget is that ArrayList is compact in memory which means that it's more cache friendly than LinkedList. LinkedList could be spread out all over RAM, while ArrayList is always snuggly packed together to take advantage of spacial locality. This has important real world ramifications.
@AminM Only the object references are compact. The objects themselves can be scattered... Until we get value types.
@swpalmer certainly. However, in a LinkedList just to FIND the item you're looking for you're touring your RAM layout. Whereas with the ArrayList you can scan through it with very few cache misses. Cache misses are a big deal for performance.
@AminM My point is that to find what you are looking for you likely still need to follow that reference and possibly suffer a cache miss. Unless all you care about is reference identity. I get that in the linked case you can suffer the cache miss just getting to the references themselves. I'm just saying Java arrays suffer from cache misses in another way as well... until Valhalla.
@swpalmer my point is that its significantly less cache misses. In the extreme. Others have posted performance comparisons here. You can be sure that you'll get much worse performance with a LinkedList almost always.
|
704

Thus far, nobody seems to have addressed the memory footprint of each of these lists besides the general consensus that aLinkedList is "lots more" than anArrayList so I did some number crunching to demonstrate exactly how much both lists take up for N null references.

Since references are either 32 or 64 bits (even when null) on their relative systems, I have included 4 sets of data for 32 and 64 bitLinkedLists andArrayLists.

Note: The sizes shown for theArrayList lines are fortrimmed lists - In practice, the capacity of the backing array in anArrayList is generally larger than its current element count.

Note 2:(thanks BeeOnRope) As CompressedOops is default now from mid JDK6 and up, the values below for 64-bit machines will basically match their 32-bit counterparts, unless of course you specifically turn it off.


Graph of LinkedList and ArrayList No. of Elements x Bytes


The result clearly shows thatLinkedList is a whole lot more thanArrayList, especially with a very high element count. If memory is a factor, steer clear ofLinkedLists.

The formulas I used follow, let me know if I have done anything wrong and I will fix it up. 'b' is either 4 or 8 for 32 or 64 bit systems, and 'n' is the number of elements. Note the reason for the mods is because all objects in java will take up a multiple of 8 bytes space regardless of whether it is all used or not.

ArrayList:

ArrayList object header + size integer + modCount integer + array reference + (array oject header + b * n) + MOD(array oject, 8) + MOD(ArrayList object, 8) == 8 + 4 + 4 + b + (12 + b * n) + MOD(12 + b * n, 8) + MOD(8 + 4 + 4 + b + (12 + b * n) + MOD(12 + b * n, 8), 8)

LinkedList:

LinkedList object header + size integer + modCount integer + reference to header + reference to footer + (node object overhead + reference to previous element + reference to next element + reference to element) * n) + MOD(node object, 8) * n + MOD(LinkedList object, 8) == 8 + 4 + 4 + 2 * b + (8 + 3 * b) * n + MOD(8 + 3 * b, 8) * n + MOD(8 + 4 + 4 + 2 * b + (8 + 3 * b) * n + MOD(8 + 3 * b, 8) * n, 8)

Masterfego's user avatar
Masterfego
2,6881 gold badge28 silver badges32 bronze badges
answeredOct 6, 2011 at 6:46
Numeron's user avatar

3 Comments

The problem with your math is that your graph greatly exaggerates the impact. You are modelling objects which each contain only anint, so 4 or 8 bytes of data. In the linked list, there are essentially 4 "words" of overhead. Your graph thus gives the impression that linked lists use "five times" the storage of array lists. This is wrong. The overhead is 16 or 32 bytes per object, as an additive adjustment, not a scaling factor.
In addition, in many cases the object will not be an integer but a big object. Say you're implementing undo in your app, so the object is the change that was made, which might be a lot of bytes. So LinkedList is still more memory than ArrayList, but only negligibly more.
Memory usage of anArrayList depends very much on usage patterns and how it has been initialised, much like Java'sByteArrayOutputStream andStringWriter. Worst case scenarios are that the array is nearly twice as large as it needs to be and on large arrays that could be a lot of wasted memory.
318

ArrayList is what you want.LinkedList is almost always a (performance) bug.

WhyLinkedList sucks:

  • It uses lots of small memory objects, and therefore impacts performance across the process.
  • Lots of small objects are bad for cache-locality.
  • Any indexed operation requires a traversal, i.e. has O(n) performance. This is not obvious in the source code, leading to algorithms O(n) slower than ifArrayList was used.
  • Getting good performance is tricky.
  • Even when big-O performance is the same asArrayList, it is probably going to be significantly slower anyway.
  • It's jarring to seeLinkedList in source because it is probably the wrong choice.
answeredNov 27, 2008 at 14:20
Tom Hawtin - tackline's user avatar

4 Comments

Try adding a million elements to a linked list and an array list and you will quickly learn that linked is orders of magnitude better for this.
@user207421 Ha, ha. I just tired it.ArrayList is over an order of magnitude faster (on my machine), and will have used less memory. (Fifth run: 2.6 ms vs 63 ms - that just a couple billionths of second per iteration for the array version.)
When adding at the end,ArrayList will always win, because even considering the worst case of having to re-allocate and copy the array log₂ n times, the number of write operations is lower than for theLinkedList, because each time, an element is added toLinkedList, a node has to be allocated and initialized and the predecessor and successor node updated. Means, writing an object header and prev/next/element references to the new node and updating next reference of the previous and prev reference of the next node. WhileArrayList converges totwo reference writes per element on avg.
@Holger And on top of that, adding an item to aLinkedList willalways involve an object allocation, whereas adding an item to anArrayList will only sometimes involve an object allocation.
194
Algorithm           ArrayList   LinkedListseek front            O(1)         O(1)seek back             O(1)         O(1)seek to index         O(1)         O(N)insert at front       O(N)         O(1)insert at back        O(1)         O(1)insert after an item  O(N)         O(1)

Algorithms: Big-Oh Notation (archived)

ArrayLists are good for write-once-read-many or appenders, but bad at add/remove from the front or middle.

drac_o's user avatar
drac_o
4475 silver badges12 bronze badges
answeredApr 8, 2010 at 20:33
Michael Munsey's user avatar

12 Comments

You can't compare big-O values directly without thinking about constant factors. For small lists (and most lists are small), ArrayList's O(N) is faster than LinkedList's O(1).
I don't care about small lists performance, and neither does my computerunless it is used in a loop somehow.
LinkedList can't really insert in the middle inO(1). It has to run through half the list to find the insertion point.
LinkedList: insert in middle O(1) - is WRONG! I found out that even insertion into 1/10th position of the LinkedList size is slower than inserting an element into 1/10th position of an ArrayList. And even worse: the end of collection. inserting into last positions (not the very last) of ArrayList is faster then into last positions (not the very last) of LinkedList
@kachanov Inserting in aLinkedListisO(1)if you have an iterator to the insert position, i.e.ListIterator.add is supposedlyO(1) for aLinkedList.
|
164

See 2021 update from author below the original answer.


Original answer (2011)

As someone who has been doing operational performance engineering on very large scale SOA web services for about a decade, I would prefer the behavior of LinkedList over ArrayList. While the steady-state throughput of LinkedList is worse and therefore might lead to buying more hardware -- the behavior of ArrayList under pressure could lead to apps in a cluster expanding their arrays in near synchronicity and for large array sizes could lead to lack of responsiveness in the app and an outage, while under pressure, which is catastrophic behavior.

Similarly, you can get better throughput in an app from the default throughput tenured garbage collector, but once you get java apps with 10GB heaps you can wind up locking up the app for 25 seconds during a Full GCs which causes timeouts and failures in SOA apps and blows your SLAs if it occurs too often. Even though the CMS collector takes more resources and does not achieve the same raw throughput, it is a much better choice because it has more predictable and smaller latency.

ArrayList is only a better choice for performance if all you mean by performance is throughput and you can ignore latency. In my experience at my job I cannot ignore worst-case latency.

Update (Aug 27, 2021 -- 10 years later)

This answer (my most historically upvoted answer on SO as well) is very likely wrong (for reasons outlined in the comments below). I'd like to add that ArrayList will optimize for sequential reading of memory and minimize cache-line and TLB misses, etc. The copying overhead when the array grows past the bounds is likely inconsequential by comparison (and can be done by efficient CPU operations). This answer is also probably getting worse over time given hardware trends. The only situations where a LinkedList might make sense would be something highly contrived where you had thousands of Lists any one of which might grow to be GB-sized, but where no good guess could be made at allocation-time of the List and setting them all to GB-sized would blow up the heap. And if you found some problem like that, then it really does call for reengineering whatever your solution is (and I don't like to lightly suggest reengineering old code because I myself maintain piles and piles of old code, but that'd be a very good case of where the original design has simply run out of runway and does need to be chucked). I'll still leave my decades-old poor opinion up there for you to read though. Simple, logical and pretty wrong.

oligofren's user avatar
oligofren
23.3k18 gold badges116 silver badges204 bronze badges
answeredJan 1, 2011 at 20:23
lamont's user avatar

7 Comments

Wouldn't another solution be managing the size of the list programmatically by using the ArrayList's ensureCapacity() method? My question is why are so many things being stored in a bunch of brittle data structures when they might better be stored in a caching or db mechanism? I had an interview the other day where they swore up and down about the evils of ArrayList, but I come here and I find that the complexity analysis is all-around better! GREAT POINT FOR DISCUSSION, THOUGH. THANKS!
once you get java apps with 10GB heaps you can wind up locking up the app for 25 seconds during a Full GCs which causes timeouts Actually with LinkedList you murder the garbage collector during full GCs, it has to iterate the overly large LinkedList with cache miss on each node.
That's... a horrible solution. you're basically reliant on the GC cleaning up for you, which is incredibly expensive, when you can just call ensureCapacity() on an arraylist instead...
@Holger An array list that increments over its capacity allocates a new list with 50% more room. For that increment you need 2.5 times the memory (and you likely need full gc cycle afterwards). I'm not concerned about day to day response time, I'm worried about running out of heap memory when a peak hour hits slightly harder than it hit yesterday and a couple big arraylists deciding they need room for 2.5 times their count for a second or two. One instance of that type of behavior during peak usage blows my sla for the whole month.
@Andreas: ALinkedListalways allocates five times the memory than a plain array of references, so anArrayList temporarily requiring 2.5 times still consumes far less memory, even while the memory is not reclaimed. Since large array allocation bypasses the Eden space, they don’t have any impact on GC behavior, unless there is really not enough memory, in which case, theLinkedList blew up much earlier…
|
149

Joshua Bloch, the author of LinkedList:

Does anyone actually use LinkedList? I wrote it, and I never use it.

Link:https://twitter.com/joshbloch/status/583813919019573248

I'm sorry for the answer not being as informative as the other answers, but I thought it would be the most self-explanatory if not revealing.

Simeon Leyzerzon's user avatar
Simeon Leyzerzon
19.1k11 gold badges60 silver badges94 bronze badges
answeredMar 1, 2017 at 10:47
Ruslan's user avatar

Comments

123

Yeah, I know, this is an ancient question, but I'll throw in my two cents:

LinkedList isalmost always the wrong choice, performance-wise. There are some very specific algorithms where a LinkedList is called for, but those are very, very rare and the algorithm will usually specifically depend on LinkedList's ability to insert and delete elements in the middle of the list relatively quickly, once you've navigated there with a ListIterator.

There is one common use case in which LinkedList outperforms ArrayList: that of a queue. However, if your goal is performance, instead of LinkedList you should also consider using an ArrayBlockingQueue (if you can determine an upper bound on your queue size ahead of time, and can afford to allocate all the memory up front), or thisCircularArrayList implementation. (Yes, it's from 2001, so you'll need to generify it, but I got comparable performance ratios to what's quoted in the article just now in a recent JVM)

answeredMay 19, 2009 at 11:21
Daniel Martin's user avatar

6 Comments

ArrayDeque is slower thanLinkedList unless all operations are at the same end. It's OK when used as a stack but it doesn't make a good queue.
Untrue - at least for Oracle's implementation in jdk1.7.0_60 and in the following test. I created a test where I loop for 10 million times and I have a Deque of 10 million random Integers. Inside the loop I poll one element from and offer a constant element. On my computer, LinkedList is over 10 times slower than ArrayDeque and uses less memory). The reason is that unlike ArrayList, ArrayDeque keeps a pointer to the head of the array so that it doesn't have to move all elements when the head is removed.
ArrayDeque is likely to be faster thanStack when used as a stack, and faster thanLinkedList when used as a queue.
Note that akhil_mittal's comment is a quote from theArrayDeque documentation.
|
90

It's an efficiency question.LinkedList is fast for appending or deleting large elements at the ends of a list, but slow to access a specific element.ArrayList is fast for accessing a specific element but can be slow to add to either end, and especially slow to delete in the middle.

Array vs ArrayList vs LinkedList vs Vector goes more in depth, as doesLinked List.

Closed Limelike Curves's user avatar
Closed Limelike Curves
1901 silver badge9 bronze badges
answeredNov 27, 2008 at 1:39
dgtized's user avatar

2 Comments

worth to mention here, thatLinkedList is fast for adding/removing only at first and last positions - then complexity will be O(1), but adding in the middle still will be O(n), because we need to run through approx n/2 elements ofLinkedList.
Is it, though?Why is an ArrayList always faster than a LinkedList found that adding 10M items to an ArrayList was faster than adding 10M items to a LinkedList. (i.e. ArrayList is faster when adding at the end, amortized over having to realloc sometimes.)
64

Correct or Incorrect: Please execute test locally and decide for yourself!

Edit/Remove is faster inLinkedList thanArrayList.

ArrayList, backed byArray, which needs to be double the size, is worse in large volume application.

Below is the unit test result for each operation.Timing is given in Nanoseconds.


Operation                       ArrayList                      LinkedList  AddAll   (Insert)               101,16719                      2623,29291 Add      (Insert-Sequentially)  152,46840                      966,62216Add      (insert-randomly)      36527                          29193remove   (Delete)               20,56,9095                     20,45,4904contains (Search)               186,15,704                     189,64,981

Here's the code:

import org.junit.Assert;import org.junit.Test;import java.util.*;public class ArrayListVsLinkedList {    private static final int MAX = 500000;    String[] strings = maxArray();    ////////////// ADD ALL ////////////////////////////////////////    @Test    public void arrayListAddAll() {        Watch watch = new Watch();        List<String> stringList = Arrays.asList(strings);        List<String> arrayList = new ArrayList<String>(MAX);        watch.start();        arrayList.addAll(stringList);        watch.totalTime("Array List addAll() = ");//101,16719 Nanoseconds    }    @Test    public void linkedListAddAll() throws Exception {        Watch watch = new Watch();        List<String> stringList = Arrays.asList(strings);        watch.start();        List<String> linkedList = new LinkedList<String>();        linkedList.addAll(stringList);        watch.totalTime("Linked List addAll() = ");  //2623,29291 Nanoseconds    }    //Note: ArrayList is 26 time faster here than LinkedList for addAll()    ///////////////// INSERT /////////////////////////////////////////////    @Test    public void arrayListAdd() {        Watch watch = new Watch();        List<String> arrayList = new ArrayList<String>(MAX);        watch.start();        for (String string : strings)            arrayList.add(string);        watch.totalTime("Array List add() = ");//152,46840 Nanoseconds    }    @Test    public void linkedListAdd() {        Watch watch = new Watch();        List<String> linkedList = new LinkedList<String>();        watch.start();        for (String string : strings)            linkedList.add(string);        watch.totalTime("Linked List add() = ");  //966,62216 Nanoseconds    }    //Note: ArrayList is 9 times faster than LinkedList for add sequentially    /////////////////// INSERT IN BETWEEN ///////////////////////////////////////    @Test    public void arrayListInsertOne() {        Watch watch = new Watch();        List<String> stringList = Arrays.asList(strings);        List<String> arrayList = new ArrayList<String>(MAX + MAX / 10);        arrayList.addAll(stringList);        String insertString0 = getString(true, MAX / 2 + 10);        String insertString1 = getString(true, MAX / 2 + 20);        String insertString2 = getString(true, MAX / 2 + 30);        String insertString3 = getString(true, MAX / 2 + 40);        watch.start();        arrayList.add(insertString0);        arrayList.add(insertString1);        arrayList.add(insertString2);        arrayList.add(insertString3);        watch.totalTime("Array List add() = ");//36527    }    @Test    public void linkedListInsertOne() {        Watch watch = new Watch();        List<String> stringList = Arrays.asList(strings);        List<String> linkedList = new LinkedList<String>();        linkedList.addAll(stringList);        String insertString0 = getString(true, MAX / 2 + 10);        String insertString1 = getString(true, MAX / 2 + 20);        String insertString2 = getString(true, MAX / 2 + 30);        String insertString3 = getString(true, MAX / 2 + 40);        watch.start();        linkedList.add(insertString0);        linkedList.add(insertString1);        linkedList.add(insertString2);        linkedList.add(insertString3);        watch.totalTime("Linked List add = ");//29193    }    //Note: LinkedList is 3000 nanosecond faster than ArrayList for insert randomly.    ////////////////// DELETE //////////////////////////////////////////////////////    @Test    public void arrayListRemove() throws Exception {        Watch watch = new Watch();        List<String> stringList = Arrays.asList(strings);        List<String> arrayList = new ArrayList<String>(MAX);        arrayList.addAll(stringList);        String searchString0 = getString(true, MAX / 2 + 10);        String searchString1 = getString(true, MAX / 2 + 20);        watch.start();        arrayList.remove(searchString0);        arrayList.remove(searchString1);        watch.totalTime("Array List remove() = ");//20,56,9095 Nanoseconds    }    @Test    public void linkedListRemove() throws Exception {        Watch watch = new Watch();        List<String> linkedList = new LinkedList<String>();        linkedList.addAll(Arrays.asList(strings));        String searchString0 = getString(true, MAX / 2 + 10);        String searchString1 = getString(true, MAX / 2 + 20);        watch.start();        linkedList.remove(searchString0);        linkedList.remove(searchString1);        watch.totalTime("Linked List remove = ");//20,45,4904 Nanoseconds    }    //Note: LinkedList is 10 millisecond faster than ArrayList while removing item.    ///////////////////// SEARCH ///////////////////////////////////////////    @Test    public void arrayListSearch() throws Exception {        Watch watch = new Watch();        List<String> stringList = Arrays.asList(strings);        List<String> arrayList = new ArrayList<String>(MAX);        arrayList.addAll(stringList);        String searchString0 = getString(true, MAX / 2 + 10);        String searchString1 = getString(true, MAX / 2 + 20);        watch.start();        arrayList.contains(searchString0);        arrayList.contains(searchString1);        watch.totalTime("Array List addAll() time = ");//186,15,704    }    @Test    public void linkedListSearch() throws Exception {        Watch watch = new Watch();        List<String> linkedList = new LinkedList<String>();        linkedList.addAll(Arrays.asList(strings));        String searchString0 = getString(true, MAX / 2 + 10);        String searchString1 = getString(true, MAX / 2 + 20);        watch.start();        linkedList.contains(searchString0);        linkedList.contains(searchString1);        watch.totalTime("Linked List addAll() time = ");//189,64,981    }    //Note: Linked List is 500 Milliseconds faster than ArrayList    class Watch {        private long startTime;        private long endTime;        public void start() {            startTime = System.nanoTime();        }        private void stop() {            endTime = System.nanoTime();        }        public void totalTime(String s) {            stop();            System.out.println(s + (endTime - startTime));        }    }    private String[] maxArray() {        String[] strings = new String[MAX];        Boolean result = Boolean.TRUE;        for (int i = 0; i < MAX; i++) {            strings[i] = getString(result, i);            result = !result;        }        return strings;    }    private String getString(Boolean result, int i) {        return String.valueOf(result) + i + String.valueOf(!result);    }}
Azeem's user avatar
Azeem
15k4 gold badges36 silver badges53 bronze badges
answeredSep 21, 2011 at 22:59
Ash's user avatar

13 Comments

ArrayList need not to be doubled, to be precise. Please check the sources first.
It should be noted that your example is flawed... You are removing from string of between: 18 + [2, 12] bytes ("true0false", "true500000false"), on average 25 bytes, which are the sizes of the elements in the middle. It's known that as element byte size increases linked list performs better, as list size increases, a contiguous array(list) will do better. Most importantly, you are doing .equals() on strings - which is not a cheap operation. If you instead used integers, I think there would be a difference.
"...is worse in large volume application": This is a misunderstanding.LinkedList has far more memory overhead because for every element there is a node object with five fields. On many systems that makes 20 bytes overhead. The average memory overhead per element forArrayList is one and a half word, which makes 6 bytes, and 8 bytes in the worst case.
I've done a better version of your benchmarkhere, with results - the append-on-end performance for the arraylist is artificially low for yours, because addAll is giving a storage array of EXACTLY initial size, so the first insert always triggers an arraycopy. Also, this includes warmup cycles to allow for JIT compilation before data is collected.
@BillK since Java 8, you can useremoveIf(element -> condition) where it fits, which can be significantly faster for anArrayList, compared to looping and removing via iterator, as it is not required to shift the entire remainder for every individual element. Whether this performs better or worse thanLinkedList depends on the particular scenario, as aLinkedList is O(1) in theory, but removing just a single node requires several memory accesses, which can easily exceed the number needed for theArrayList when removing a significant number of elements.
|
59

ArrayList is essentially an array.LinkedList is implemented as a double linked list.

Theget is pretty clear. O(1) forArrayList, becauseArrayList allow random access by using index. O(n) forLinkedList, because it needs to find the index first. Note: there are different versions ofadd andremove.

LinkedList is faster in add and remove, but slower in get. In brief,LinkedList should be preferred if:

  1. there are no large number of random access of element
  2. there are a large number of add/remove operations

===ArrayList ===

  • add(E e)
    • add at the end of ArrayList
    • require memory resizing cost.
    • O(n) worst, O(1) amortized
  • add(int index, E element)
    • add to a specific index position
    • require shifting & possible memory resizing cost
    • O(n)
  • remove(int index)
    • remove a specified element
    • require shifting & possible memory resizing cost
    • O(n)
  • remove(Object o)
    • remove the first occurrence of the specified element from this list
    • need to search the element first, and then shifting & possible memory resizing cost
    • O(n)

===LinkedList ===

  • add(E e)

    • add to the end of the list
    • O(1)
  • add(int index, E element)

    • insert at specified position
    • need to find the position first
    • O(n)
  • remove()
    • remove first element of the list
    • O(1)
  • remove(int index)
    • remove element with specified index
    • need to find the element first
    • O(n)
  • remove(Object o)
    • remove the first occurrence of the specified element
    • need to find the element first
    • O(n)

Here is a figure fromprogramcreek.com (add andremove are the first type, i.e., add an element at the end of the list and remove the element at the specified position in the list.):

enter image description here

Premraj's user avatar
Premraj
75.4k27 gold badges246 silver badges186 bronze badges
answeredApr 21, 2013 at 0:03
Ryan's user avatar

1 Comment

"LinkedList is faster than add/remove". Wrong, check the answer abovestackoverflow.com/a/7507740/638670
59

TL;DR due to modern computer architecture,ArrayList will be significantly more efficient for nearly any possible use-case - and thereforeLinkedList should be avoided except some very unique and extreme cases.


In theory, LinkedList has an O(1) for theadd(E element)

Also adding an element in the mid of a list should be very efficient.

Practice is very different, as LinkedList is aCache Hostile Data structure. From performance POV - there are very little cases whereLinkedList could be better performing than theCache-friendlyArrayList.

Here are results of a benchmark testing inserting elements in random locations. As you can see - the array list if much more efficient, although in theory each insert in the middle of the list will require "move" then later elements of the array (lower values are better):

enter image description here

Working on a later generation hardware (bigger, more efficient caches) - the results are even more conclusive:

enter image description here

LinkedList takes much more time to accomplish the same job.sourceSource Code

There are two main reasons for this:

  1. Mainly - that the nodes of theLinkedList are scattered randomly across the memory. RAM ("Random Access Memory") isn't really random and blocks of memory need to be fetched to cache. This operation takes time, and when such fetches happen frequently - the memory pages in the cache need to be replaced all the time -> Cache misses -> Cache is not efficient.ArrayList elements are stored on continuous memory - which is exactly what the modern CPU architecture is optimizing for.

  2. SecondaryLinkedList required to hold back/forward pointers, which means 3 times the memory consumption per value stored compared toArrayList.

DynamicIntArray, btw, is a custom ArrayList implementation holdingInt (primitive type) and not Objects - hence all data is really stored adjacently - hence even more efficient.

A key elements to remember is that the cost of fetching memory block, is more significant than the cost accessing a single memory cell. That's why reader 1MB of sequential memory is up to x400 times faster than reading this amount of data from different blocks of memory:

Latency Comparison Numbers (~2012)----------------------------------L1 cache reference                           0.5 nsBranch mispredict                            5   nsL2 cache reference                           7   ns                      14x L1 cacheMutex lock/unlock                           25   nsMain memory reference                      100   ns                      20x L2 cache, 200x L1 cacheCompress 1K bytes with Zippy             3,000   ns        3 usSend 1K bytes over 1 Gbps network       10,000   ns       10 usRead 4K randomly from SSD*             150,000   ns      150 us          ~1GB/sec SSDRead 1 MB sequentially from memory     250,000   ns      250 usRound trip within same datacenter      500,000   ns      500 usRead 1 MB sequentially from SSD*     1,000,000   ns    1,000 us    1 ms  ~1GB/sec SSD, 4X memoryDisk seek                           10,000,000   ns   10,000 us   10 ms  20x datacenter roundtripRead 1 MB sequentially from disk    20,000,000   ns   20,000 us   20 ms  80x memory, 20X SSDSend packet CA->Netherlands->CA    150,000,000   ns  150,000 us  150 ms

Source:Latency Numbers Every Programmer Should Know

Just to make the point even clearer, please check the benchmark of adding elements to the beginning of the list. This is a use-case where, in-theory, theLinkedList should really shine, andArrayList should present poor or even worse-case results:

enter image description here

Note: this is a benchmark of the C++ Std lib, but my previous experience shown the C++ and Java results are very similar.Source Code

Copying a sequential bulk of memory is an operation optimized by the modern CPUs - changing theory and actually making, again,ArrayList/Vector much more efficient


Credits: All benchmarks posted here are created byKjell Hedström. Even more data can be found onhis blog

answeredOct 19, 2018 at 2:53
Lior Bar-On's user avatar

3 Comments

I wouldn't call a queue unique or extreme! A fifo queue is much easier implemented on a LinkedList instead of an ArrayList. It's actually a nightmare on an ArrayList as you have to track your own start, stop and do your own reallocating, you might as well use an array, but a Linked List IS a fifo. I'm not sure about Java's implementation, but a LinkedList can do O(1) for both queue and dequeue operations (Requires a special pointer to the tail element for the remove, which I assume java has but I haven't double-checked.)
inserting into the middle of aArrayList array uses the native methodjava.lang.System.arraycopy() which is written in C++ in the OpenJDK. so while in theory aLinkedList has less work to do in practice there are so many extra-linguistic mechanisms that make "Big O" largely irrelevant. Particularly how cache friendly things are as per this excellent answer.
Thanks, but something isn't right with the last benchmark. 1) Why "list" duration even grows? If elements are always inserted at the start (0 index), it doesn't depend on size. And if you meant inserting around the start, then how close this "around" is plays big role - in Java, inserting 1000th element into prebuilt 100_000 array (multiple times) is still faster for LinkedList, and only becomes slower when you get closer to end. 2) So right now around-start-insertion in Java is still faster for LinkedList. Though, I'd advise trick here - just reverse the list before working with it.
39

ArrayList is randomly accessible, whileLinkedList is really cheap to expand and remove elements from. For most cases,ArrayList is fine.

Unless you've created large lists and measured a bottleneck, you'll probably never need to worry about the difference.

Azeem's user avatar
Azeem
15k4 gold badges36 silver badges53 bronze badges
answeredNov 27, 2008 at 1:41
Dustin's user avatar

9 Comments

LinkedList is not cheap to add elements to. It is almost always quicker to add a million elements to an ArrayList than to add them to a LinkedList. And most lists in real-world code are not even a million elements long.
At any given point, you know the cost of adding an item to your LinkedList. The ArrayList you do not (in general). Adding a single item to an ArrayList containing a million itemscould take a very long time -- it's an O(n) operation plus double the storage unless you preallocated space. Adding an item to a LinkedList is O(1). My last statement stands.
Adding a single item to an ArrayList is O(1) no matter it is 1 million or 1 billion. Adding an item to a LinkedList is also O(1). "Adding" means ADDING TO THE END.
You must've read the implementation differently than I do. In my experience, copying a 1 billion element array takes longer than copying a 1 million element array.
@kachanov you must misunderstand Dustin. Unless you have declared an array of 1 billion items you will eventually need to resize your array in which case you will need to copy all elements into a new bigger array hence sometimes you will get O (N) however with a linked list you will always get O (1)
|
33

You can use one over the other based on the time complexities of the operations that you'd perform on that particular List.

|---------------------|---------------------|--------------------|------------||      Operation      |     ArrayList       |     LinkedList     |   Winner   ||---------------------|---------------------|--------------------|------------||     get(index)      |       O(1)          |         O(n)       | ArrayList  ||                     |                     |  n/4 steps in avg  |            ||---------------------|---------------------|--------------------|------------||      add(E)         |       O(1)          |         O(1)       | LinkedList ||                     |---------------------|--------------------|            ||                     | O(n) in worst case  |                    |            ||---------------------|---------------------|--------------------|------------||    add(index, E)    |       O(n)          |         O(n)       | LinkedList ||                     |     n/2 steps       |      n/4 steps     |            ||                     |---------------------|--------------------|            ||                     |                     |  O(1) if index = 0 |            ||---------------------|---------------------|--------------------|------------||  remove(index, E)   |       O(n)          |         O(n)       | LinkedList ||                     |---------------------|--------------------|            ||                     |     n/2 steps       |      n/4 steps     |            ||---------------------|---------------------|--------------------|------------||  Iterator.remove()  |       O(n)          |         O(1)       | LinkedList ||  ListIterator.add() |                     |                    |            ||---------------------|---------------------|--------------------|------------||--------------------------------------|-----------------------------------||              ArrayList               |            LinkedList             ||--------------------------------------|-----------------------------------||     Allows fast read access          |   Retrieving element takes O(n)   ||--------------------------------------|-----------------------------------||   Adding an element require shifting | o(1) [but traversing takes time]  ||       all the later elements         |                                   ||--------------------------------------|-----------------------------------||   To add more elements than capacity ||    new array need to be allocated    ||--------------------------------------|
answeredJan 14, 2019 at 12:54
Gayan Weerakutti's user avatar

1 Comment

The ArrayDeque balances things a bit more towards the arrays since insert/remove front/back are all O(1) the only thing Linked List still wins at is adding/removing while traversing (the Iterator operations).
27

If your code hasadd(0) andremove(0), use aLinkedList and it's prettieraddFirst() andremoveFirst() methods. Otherwise, useArrayList.

And of course,Guava'sImmutableList is your best friend.

Azeem's user avatar
Azeem
15k4 gold badges36 silver badges53 bronze badges
answeredNov 28, 2008 at 2:04
Jesse Wilson's user avatar

5 Comments

For small lists, ArrayList.add(0) is still always going to be faster than LinkedList.addFirst().
@Porculus I am constantly hearing this argument that for small lists ArrayList.add(0) will be faster, this small is how much small? 10 elements, 10 million, ?
@garg10may small is less than 10.
@Porculus small means less than the max capacity of the internal array underlying the ArrayList.
As of JDK 21, all lists (including ArrayList) have addFirst/addLast, getFirst/getLast, and removeFirst/removeLast methods. On ArrayList the implementation of addFirst(e) is essentially add(0, e) but if you're after prettiness these methods are all on ArrayList now.
25

Let's compare LinkedList and ArrayList w.r.t. below parameters:

1. Implementation

ArrayList is the resizable array implementation of list interface , while

LinkedList is the Doubly-linked list implementation of the list interface.


2. Performance

  • get(int index) or search operation

    ArrayList get(int index) operation runs in constant time i.e O(1) while

    LinkedList get(int index) operation run time is O(n) .

    The reason behindArrayList being faster than LinkedList is that ArrayList uses an index based system for its elements as it internally uses an array data structure, on the other hand,

    LinkedList does not provide index-based access for its elements as it iterates either from the beginning or end (whichever is closer) to retrieve the node at the specified element index.

  • insert() or add(Object) operation

    Insertions inLinkedList are generally fast as compare to ArrayList. In LinkedList adding or insertion is O(1) operation .

    While inArrayList, if the array is the full i.e worst case, there is an extra cost of resizing array and copying elements to the new array, which makes runtime of add operation in ArrayList O(n), otherwise it is O(1).

  • remove(int) operation

    Remove operation in LinkedList is generally the same as ArrayList i.e. O(n).

    InLinkedList, there are two overloaded remove methods. one is remove() without any parameter which removes the head of the list and runs in constant time O(1). The other overloaded remove method in LinkedList is remove(int) or remove(Object) which removes the Object or int passed as a parameter. This method traverses the LinkedList until it found the Object and unlink it from the original list. Hence this method runtime is O(n).

    While inArrayList remove(int) method involves copying elements from the old array to new updated array, hence its runtime is O(n).


3. Reverse Iterator

LinkedList can be iterated in reverse direction using descendingIterator() while

there is no descendingIterator() inArrayList , so we need to write our own code to iterate over the ArrayList in reverse direction.


4. Initial Capacity

If the constructor is not overloaded, thenArrayList creates an empty list of initial capacity 10, while

LinkedList only constructs the empty list without any initial capacity.


5. Memory Overhead

Memory overhead inLinkedList is more as compared to ArrayList as a node in LinkedList needs to maintain the addresses of the next and previous node. While

InArrayList each index only holds the actual object(data).


Source

Yoon5oo's user avatar
Yoon5oo
5146 silver badges12 bronze badges
answeredFeb 10, 2017 at 15:14
Abhijeet Ashok Muneshwar's user avatar

Comments

24

I know this is an old post, but I honestly can't believe nobody mentioned thatLinkedList implementsDeque. Just look at the methods inDeque (andQueue); if you want a fair comparison, try runningLinkedList againstArrayDeque and do a feature-for-feature comparison.

Azeem's user avatar
Azeem
15k4 gold badges36 silver badges53 bronze badges
answeredApr 19, 2013 at 7:26
Ajax's user avatar

Comments

22

Here is the Big-O notation in bothArrayList andLinkedList and alsoCopyOnWrite-ArrayList:

ArrayList

get                 O(1)add                 O(1)contains            O(n)next                O(1)remove              O(n)iterator.remove     O(n)

LinkedList

get                 O(n)add                 O(1)contains            O(n)next                O(1)remove              O(1)iterator.remove     O(1)

CopyOnWrite-ArrayList

get                 O(1)add                 O(n)contains            O(n)next                O(1)remove              O(n)iterator.remove     O(n)

Based on these you have to decide what to choose. :)

Azeem's user avatar
Azeem
15k4 gold badges36 silver badges53 bronze badges
answeredNov 6, 2012 at 14:32
Rajith Delantha's user avatar

3 Comments

>>>> ArrayList add --> O(1) <- not tru. In some cases ArrayList will have to grow to add one more element
LinkedList remove is not O(1), it would need to search for the element to be removed, therefore worst case O(n) and average O(n/2)
Neither isLinkedList.add(), although most of the answers here say so.
17

In addition to the other good arguments above, you should noticeArrayList implementsRandomAccess interface, whileLinkedList implementsQueue.

So, somehow they address slightly different problems, with difference of efficiency and behavior (see their list of methods).

Azeem's user avatar
Azeem
15k4 gold badges36 silver badges53 bronze badges
answeredNov 27, 2008 at 1:47
PhiLho's user avatar

Comments

12

It depends upon what operations you will be doing more on the List.

ArrayList is faster to access an indexed value. It is much worse when inserting or deleting objects.

To find out more, read any article that talks about the difference between arrays and linked lists.

Azeem's user avatar
Azeem
15k4 gold badges36 silver badges53 bronze badges
answeredNov 27, 2008 at 1:42
Matthew Schinckel's user avatar

1 Comment

To find out more do not read, just write the code. and you will find out that ArrayList implementation is faster then LinkedList in insertion and deletion.
11
answeredSep 5, 2011 at 6:33
chharvey's user avatar

1 Comment

Hi @chharvey , Link only answers get 6 Upvotes ? Please add some points that could support the link .What if oracle changes their link?
10

An array list is essentially an array with methods to add items etc. (and you should use a generic list instead). It is a collection of items which can be accessed through an indexer (for example [0]). It implies a progression from one item to the next.

A linked list specifies a progression from one item to the next (Item a -> item b). You can get the same effect with an array list, but a linked list absolutely says what item is supposed to follow the previous one.

answeredApr 20, 2010 at 15:32
kemiller2002's user avatar

Comments

10

An important feature of a linked list (which I didn't read in another answer) is the concatenation of two lists. With an array this is O(n) (+ overhead of some reallocations) with a linked list this is only O(1) or O(2) ;-)

Important: For Java itsLinkedList this is not true! SeeIs there a fast concat method for linked list in Java?

answeredMar 22, 2010 at 22:32
Karussell's user avatar

2 Comments

How is that? This may be true with linked list data structures but not a Java LinkList object. You can't just point anext from one list to the first node in the second list. The only way is to useaddAll() which adds elements sequentially, though it is better than looping through and callingadd() for each element. To do this quickly in O(1) you would need a compositing class (like org.apache.commons.collections.collection.CompositeCollection) but then this would work for any kind of List/Collection.
yes, true. I edited the answer accordingly. but see this answer for 'how' to do it with LinkedList:stackoverflow.com/questions/2494031/…
9

ArrayList and LinkedList have their own pros and cons.

ArrayList uses contiguous memory address compared to LinkedList which uses pointers toward the next node. So when you want to look up an element in an ArrayList is faster than doing n iterations with LinkedList.

On the other hand, insertion and deletion in a LinkedList are much easier because you just have to change the pointers whereas an ArrayList implies the use of shift operation for any insertion or deletion.

If you have frequent retrieval operations in your app use an ArrayList. If you have frequent insertion and deletion use a LinkedList.

answeredMay 15, 2017 at 18:06
Nesan Mano's user avatar

Comments

9

1) Underlying Data Structure

The first difference between ArrayList and LinkedList comes with the fact that ArrayList is backed by Array while LinkedList is backed by LinkedList. This will lead to further differences in performance.

2) LinkedList implements Deque

Another difference between ArrayList and LinkedList is that apart from the List interface, LinkedList also implements Deque interface, which provides first in first out operations foradd() andpoll() and several other Deque functions. 3) Adding elements in ArrayList Adding element in ArrayList is O(1) operation if it doesn't trigger re-size of Array, in which case it becomes O(log(n)), On the other hand, appending an element in LinkedList is O(1) operation, as it doesn't require any navigation.

4) Removing an element from a position

In order to remove an element from a particular index e.g. by callingremove(index), ArrayList performs a copy operation which makes it close to O(n) while LinkedList needs to traverse to that point which also makes it O(n/2), as it can traverse from either direction based upon proximity.

5) Iterating over ArrayList or LinkedList

Iteration is the O(n) operation for both LinkedList and ArrayList where n is a number of an element.

6) Retrieving element from a position

Theget(index) operation is O(1) in ArrayList while its O(n/2) in LinkedList, as it needs to traverse till that entry. Though, in Big O notation O(n/2) is just O(n) because we ignore constants there.

7) Memory

LinkedList uses a wrapper object, Entry, which is a static nested class for storing data and two nodes next and previous while ArrayList just stores data in Array.

So memory requirement seems less in the case of ArrayList than LinkedList except for the case where Array performs the re-size operation when it copies content from one Array to another.

If Array is large enough it may take a lot of memory at that point and trigger Garbage collection, which can slow response time.

From all the above differences between ArrayList vs LinkedList, It looks ArrayList is the better choice than LinkedList in almost all cases, except when you do a frequentadd() operation thanremove(), orget().

It's easier to modify a linked list than ArrayList, especially if you are adding or removing elements from start or end because linked list internally keeps references of those positions and they are accessible in O(1) time.

In other words, you don't need to traverse through the linked list to reach the position where you want to add elements, in that case, addition becomes O(n) operation. For example, inserting or deleting an element in the middle of a linked list.

In my opinion, use ArrayList over LinkedList for most of the practical purpose in Java.

Wolfson's user avatar
Wolfson
1,4372 gold badges21 silver badges26 bronze badges
answeredJun 7, 2018 at 10:33
Anjali Suman's user avatar

1 Comment

I think this is the best stated answer of the entire group here. It's accurate and informative. I would suggest changing the last line--at the end add "aside from queues" which are very important structures that really don't make sense for a linked list at all.
7

I have read the responses, but there is one scenario where I always use a LinkedList over an ArrayList that I want to share to hear opinions:

Every time I had a method that returns a list of data obtained from a DB I always use a LinkedList.

My rationale was that because it is impossible to know exactly how many results am I getting, there will be not memory wasted (as in ArrayList with the difference between the capacity and actual number of elements), and there would be no time wasted trying to duplicate the capacity.

As far a ArrayList, I agree that at least you should always use the constructor with the initial capacity, to minimize the duplication of the arrays as much as possible.

answeredOct 3, 2011 at 23:23
gaijinco's user avatar

1 Comment

LinkedList has a much higher overhead per element (3 pointers per element).ArrayList has 1 pointer per element. So even if theArrayList is only half filled, it will never have more overhead thanLinkedList.
7

ArrayList andLinkedList both implementsList interface and their methods and results are almost identical. However there are few differences between them which make one better over another depending on the requirement.

ArrayList Vs LinkedList

1)Search:ArrayList search operation is pretty fast compared to theLinkedList search operation.get(int index) inArrayList gives the performance ofO(1) whileLinkedList performance isO(n).

Reason:ArrayList maintains index based system for its elements as it uses array data structure implicitly which makes it faster for searching an element in the list. On the other sideLinkedList implements doubly linked list which requires the traversal through all the elements for searching an element.

2)Deletion:LinkedList remove operation givesO(1) performance whileArrayList gives variable performance:O(n) in worst case (while removing first element) andO(1) in best case (While removing last element).

Conclusion: LinkedList element deletion is faster compared to ArrayList.

Reason: LinkedList’s each element maintains two pointers (addresses) which points to the both neighbor elements in the list. Hence removal only requires change in the pointer location in the two neighbor nodes (elements) of the node which is going to be removed. While In ArrayList all the elements need to be shifted to fill out the space created by removed element.

3)Inserts Performance:LinkedList add method givesO(1) performance whileArrayList givesO(n) in worst case. Reason is same as explained for remove.

4)Memory Overhead:ArrayList maintains indexes and element data whileLinkedList maintains element data and two pointers for neighbor nodes

hence the memory consumption is high in LinkedList comparatively.

There are few similarities between these classes which are as follows:

  • Both ArrayList and LinkedList are implementation of List interface.
  • They both maintain the elements insertion order which means while displaying ArrayList and LinkedList elements the result set would be having the same order in which the elements got inserted into the List.
  • Both these classes are non-synchronized and can be made synchronized explicitly by using Collections.synchronizedList method.
  • Theiterator andlistIterator returned by these classes arefail-fast (if list is structurally modified at any time after the iterator is created, in any way except through theiterator’s own remove or add methods, the iterator willthrow aConcurrentModificationException).

When to use LinkedList and when to use ArrayList?

  • As explained above the insert and remove operations give good performance(O(1)) inLinkedList compared toArrayList(O(n)).

    Hence if there is a requirement of frequent addition and deletion in application then LinkedList is a best choice.

  • Search (get method) operations are fast inArraylist (O(1)) but not inLinkedList (O(n))

    so If there are less add and remove operations and more search operations requirement, ArrayList would be your best bet.

answeredNov 2, 2016 at 9:00
Real73's user avatar

Comments

6

Operation get(i) in ArrayList is faster than LinkedList, because:
ArrayList: Resizable-array implementation of the List interface
LinkedList: Doubly-linked list implementation of the List and Deque interfaces

Operations that index into the list will traverse the list from the beginning or the end, whichever is closer to the specified index.

L Joey's user avatar
L Joey
1552 silver badges8 bronze badges
answeredApr 25, 2013 at 7:57
王奕然's user avatar

Comments

5

Bothremove() andinsert() have a runtime efficiency of O(n) for both ArrayLists and LinkedLists. However, the reason behind the linear processing time comes from two very different reasons:

In an ArrayList, you get to the element in O(1), but actually removing or inserting something makes it O(n) because all the following elements need to be changed.

In a LinkedList, it takes O(n) to actually get to the desired element, because we have to start at the very beginning until we reach the desired index. Actually removing or inserting is constant, because we only have to change 1 reference forremove() and 2 references forinsert().

Which of the two is faster for inserting and removing depends on where it happens. If we are closer to the beginning the LinkedList will be faster, because we have to go through relatively few elements. If we are closer to the end an ArrayList will be faster, because we get there in constant time and only have to change the few remaining elements that follow it. When done precisely in the middle the LinkedList will be faster because going through n elements is quicker than moving n values.

Bonus: While there is no way of making these two methods O(1) for an ArrayList, there actually is a way to do this in LinkedLists. Let's say we want to go through the entire List removing and inserting elements on our way. Usually, you would start from the very beginning for each element using the LinkedList, we could also "save" the current element we're working on with an Iterator. With the help of the Iterator, we get an O(1) efficiency forremove() andinsert() when working in a LinkedList. Making it the only performance benefit I'm aware of where a LinkedList is always better than an ArrayList.

Wolfson's user avatar
Wolfson
1,4372 gold badges21 silver badges26 bronze badges
answeredJun 11, 2016 at 20:40
pietz's user avatar

Comments

4

One of the tests I saw on here only conducts the test once. But what I have noticed is that you need to run these tests many times and eventually their times will converge. Basically the JVM needs to warm up. For my particular use case I needed to add/remove items to a list that grows to about 500 items. In my testsLinkedList came out faster, withLinkedList coming in around 50,000 NS andArrayList coming in at around 90,000 NS... give or take. See the code below.

public static void main(String[] args) {    List<Long> times = new ArrayList<>();    for (int i = 0; i < 100; i++) {        times.add(doIt());    }    System.out.println("avg = " + (times.stream().mapToLong(x -> x).average()));}static long doIt() {    long start = System.nanoTime();    List<Object> list = new LinkedList<>();    //uncomment line below to test with ArrayList    //list = new ArrayList<>();    for (int i = 0; i < 500; i++) {        list.add(i);    }    Iterator it = list.iterator();    while (it.hasNext()) {        it.next();        it.remove();    }    long end = System.nanoTime();    long diff = end - start;    //uncomment to see the JVM warmup and get faster for the first few iterations    //System.out.println(diff)    return diff;}
answeredAug 4, 2018 at 18:52
Jose Martinez's user avatar

Comments

3

ArrayList extends AbstractList and implements the List Interface. ArrayList is dynamic array.
It can be said that it was basically created to overcome the drawbacks of arrays

The LinkedList class extends AbstractSequentialList and implements List,Deque, and Queue interface.
Performance
arraylist.get() is O(1) whereaslinkedlist.get() is O(n)
arraylist.add() is O(1) andlinkedlist.add() is 0(1)
arraylist.contains() is O(n) andlinkedlist.contains() is O(n)
arraylist.next() is O(1) andlinkedlist.next() is O(1)
arraylist.remove() is O(n) whereaslinkedlist.remove() is O(1)
In arraylist
iterator.remove() is O(n)
whereas In linkedlist
iterator.remove()is O(1)

answeredFeb 20, 2018 at 21:51
Randhawa's user avatar

Comments

Protected question. To answer this question, you need to have at least 10 reputation on this site (not counting theassociation bonus). The reputation requirement helps protect this question from spam and non-answer activity.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.