LinkedList<E> allows for constant-time insertions or removals *using iterators*, but only sequential access of elements. In other words, you can walk the list forwards or backward, 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 are *O(n)* (*n/4* steps) on average, though *O(1)* for index = 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 is allocated, and the old array is copied to the new one, so adding to an ArrayList is *O(n)* in the worst case but constant on average.

So depending on the operations you intend to do, you should choose the implementations accordingly.