Resumo ArrayList com ArrayDequeé preferível em muitos mais casos de uso do que LinkedList. Se você não tiver certeza, basta começar ArrayList.
LinkedListe ArrayListsão duas implementações diferentes da interface da lista. LinkedListimplementa-o com uma lista duplamente vinculada. ArrayListimplementa-o com uma matriz de redimensionamento dinâmico.
Como nas operações de lista e matriz vinculadas padrão, os vários métodos terão tempos de execução algorítmicos diferentes.
Para LinkedList<E>
get(int index)é O (n) (com n / 4 etapas em média), mas O (1) quando index = 0ou index = list.size() - 1(nesse caso, você também pode usar getFirst()e getLast()). Um dos principais benefícios de LinkedList<E>
add(int index, E element)é O (n) (com n / 4 etapas em média), mas O (1) quando index = 0ou index = list.size() - 1(nesse caso, você também pode usar addFirst()e addLast()/ add()). Um dos principais benefícios de LinkedList<E>
remove(int index)é O (n) (com n / 4 etapas em média), mas O (1) quando index = 0ou index = list.size() - 1(nesse caso, você também pode usar removeFirst()e removeLast()). Um dos principais benefícios de LinkedList<E>
Iterator.remove()é O (1) . Um dos principais benefícios de LinkedList<E>
ListIterator.add(E element)é O (1) . Um dos principais benefícios de LinkedList<E>
Nota: Muitas das operações precisam de n / 4 etapas, em média, número constante de etapas no melhor caso (por exemplo, índice = 0) e n / 2 etapas no pior caso (meio da lista)
Para ArrayList<E>
get(int index)é O (1) . Principal benefício de ArrayList<E>
add(E element)é O (1) amortizado, mas O (n) na pior das hipóteses, pois a matriz deve ser redimensionada e copiada
add(int index, E element)é O (n) (com n / 2 passos em média)
remove(int index)é O (n) (com n / 2 passos em média)
Iterator.remove()é O (n) (com n / 2 passos em média)
ListIterator.add(E element)é O (n) (com n / 2 passos em média)
Nota: Muitas das operações precisam de n / 2 etapas, em média, número constante de etapas no melhor caso (final da lista), n etapas no pior caso (início da lista)
LinkedList<E>permite inserções ou remoções em tempo constante usando iteradores , mas apenas acesso seqüencial aos elementos. Em outras palavras, você pode percorrer a lista para frente ou para trás, mas encontrar uma posição na lista leva um tempo proporcional ao tamanho da lista. Javadoc diz que "as operações indexadas na lista percorrerão a lista do começo ou do fim, o que estiver mais próximo" , então esses métodos são O (n) ( n / 4 passos) em média, embora O (1) para index = 0.
ArrayList<E>, por outro lado, permita acesso rápido de leitura aleatória, para que você possa pegar qualquer elemento em tempo constante. Mas adicionar ou remover de qualquer lugar, exceto o final, exige a troca de todos os últimos elementos, seja para fazer uma abertura ou preencher a lacuna. Além disso, se você adicionar mais elementos do que a capacidade da matriz subjacente, uma nova matriz (1,5 vezes o tamanho) será alocada e a matriz antiga será copiada para a nova. Portanto, adicionar a um ArrayListé O (n) na pior das hipóteses. caso, mas constante, em média.
Portanto, dependendo das operações que você pretende executar, escolha as implementações adequadamente. A iteração sobre qualquer tipo de lista é praticamente igualmente barata. (Iterar sobre um ArrayListé tecnicamente mais rápido, mas, a menos que você esteja fazendo algo realmente sensível ao desempenho, não se preocupe com isso - as duas são constantes.)
Os principais benefícios do uso de um LinkedListsurgem quando você reutiliza os iteradores existentes para inserir e remover elementos. Essas operações podem ser realizadas em O (1) , alterando apenas a lista localmente. Em uma lista de matrizes, o restante da matriz precisa ser movido (ou seja, copiado). Por outro lado, procurar de uma LinkedListmaneira seguir os links em O (n) ( n / 2 passos) para o pior caso, enquanto que em uma ArrayListposição desejada pode ser computado matematicamente e acessado em O (1) .
Outro benefício do uso de a LinkedListsurge quando você adiciona ou remove do cabeçalho da lista, pois essas operações são O (1) , enquanto são O (n) para ArrayList. Observe que ArrayDequepode ser uma boa alternativa LinkedListpara adicionar e remover da cabeça, mas não é a List.
Além disso, se você tiver listas grandes, lembre-se de que o uso de memória também é diferente. Cada elemento de a LinkedListtem mais sobrecarga, já que os ponteiros para os elementos seguinte e anterior também são armazenados. ArrayListsnão tem essa sobrecarga. No entanto, ArrayListsocupe a quantidade de memória alocada para a capacidade, independentemente de os elementos terem sido realmente adicionados.
A capacidade inicial padrão de um ArrayListé bem pequena (10 de Java 1.4 - 1.8). Mas como a implementação subjacente é uma matriz, ela deverá ser redimensionada se você adicionar muitos elementos. Para evitar o alto custo de redimensionamento quando você sabe que irá adicionar muitos elementos, construa-o ArrayListcom uma capacidade inicial mais alta.