Estou tentando entender por que o ArrayDeque do Java é melhor que o LinkedList do Java, pois ambos implementam a interface Deque.
Quase não vejo alguém usando ArrayDeque em seu código. Se alguém esclarecer como o ArrayDeque é implementado, seria útil.
Se eu entender, ficarei mais confiante em usá-lo. Eu não conseguia entender claramente a implementação do JDK quanto à maneira como ele gerencia as referências de cabeçalho e cauda.
java
deque
linked-list
arraydeque
Cruel
fonte
fonte
src.zip
. É o arquivo com o código fonte das classes java. Eu recomendo vivamente estudar a estrutura e as classes internas dessas classes para entender melhor como as classes java funcionam.Respostas:
Estruturas vinculadas são possivelmente a pior estrutura para iterar com uma falta de cache em cada elemento. Além disso, eles consomem muito mais memória.
Se você precisar adicionar / remover ambas as extremidades, o ArrayDeque é significativamente melhor que uma lista vinculada. O acesso aleatório a cada elemento também é O (1) para uma fila cíclica.
A única operação melhor de uma lista vinculada é remover o elemento atual durante a iteração.
fonte
LinkedList
implementaList
enquantoArrayDeque
não. Isso significa queLinkedList
existem métodos comoindexOf
ouremove(int)
enquantoArrayDeque
não. Às vezes pode ser importante.Acredito que o principal gargalo de desempenho
LinkedList
é o fato de que, sempre que você avança para qualquer extremidade do deque, nos bastidores, a implementação aloca um novo nó de lista vinculado, que envolve essencialmente JVM / OS, e isso é caro. Além disso, sempre que você salta de qualquer extremidade, os nós internosLinkedList
se tornam elegíveis para a coleta de lixo e isso é mais trabalhoso nos bastidores. Além disso, como os nós da lista vinculada são alocados aqui e ali, o uso do cache da CPU não trará muitos benefícios.Se puder ser interessante, tenho uma prova de que adicionar (anexar) um elemento
ArrayList
ou serArrayDeque
executado em tempo constante amortizado; consulte isso .fonte
ArrayDeque
é novo no Java 6, e é por isso que muitos códigos (especialmente projetos que tentam ser compatíveis com versões anteriores do Java) não o usam.É "melhor" em alguns casos, porque você não está alocando um nó para cada item a ser inserido; todos os elementos são armazenados em uma matriz gigante, que é redimensionada se ficar cheia.
fonte
Todas as pessoas que criticam a
LinkedList
, pensam em todos os outros usuários que usamList
Java, provavelmente usamArrayList
e naLinkedList
maioria das vezes porque estiveram antes do Java 6 e porque essas são as que estão sendo ensinadas como um começo na maioria dos livros.Mas, isso não significa, eu cegamente tomar
LinkedList
's ouArrayDeque
s lado'. Se você quiser saber, dê uma olhada no benchmark abaixo feito por Brian .A configuração do teste considera:
Resultado do teste:
Gráfico:
Leve embora:
ArrayList
ouArrayDeque
com um bom palpite sobre a capacidade máxima que a lista pode exigir devido a uma restrição restrita de memória.LinkedList
procedimento tão cuidadoso ao decidir usar um,ArrayDeque
especialmente porque ele não implementa aList
interface (acho que esse é o motivo). Pode ser que sua base de código converse com a interface da lista extensivamente, provavelmente e você decida usar umArrayDeque
. Usá-lo para implementações internas pode ser uma boa ideia ...fonte
ArrayDeque e LinkedList estão implementando a interface Deque , mas a implementação é diferente.
Principais diferenças:
A classe ArrayDeque é a implementação redimensionável da interface Deque e a classe LinkedList é a implementação da lista
Elementos NULL podem ser adicionados ao LinkedList, mas não no ArrayDeque
ArrayDeque é mais eficiente que o LinkedList para adicionar e remover operações nas duas extremidades e a implementação do LinkedList é eficiente para remover o elemento atual durante a iteração
A implementação LinkedList consome mais memória que o ArrayDeque
Portanto, se você não precisa suportar elementos NULL e procurar menos memória e eficiência de adicionar / remover elementos nas duas extremidades, o ArrayDeque é o melhor
Consulte a documentação para mais detalhes.
fonte
header.previous.element
). A alegação "a eficiência da memória" também pode ser contestada desde a matriz de suporte é sempre redimensionada para a próxima potência de 2.Iterator
para acessar o último elemento, a operação é O (N) para ambas as classes. Quando você usa aDeque
interface comum , o acesso ao último elemento é O (1) para ambas as classes. Independentemente de qual ponto de vista você adotar, atribuir O (1) aArrayDeque
e O (N) aoLinkedList
mesmo tempo está errado.embora
ArrayDeque<E>
eLinkedList<E>
tenham ambos implementado aDeque<E>
interface, mas o ArrayDeque usa basicamente o array de objetosE[]
para manter os elementos dentro do objeto, portanto geralmente usa o índice para localizar os elementos de cabeçalho e cauda.Em uma palavra, funciona apenas como Deque (com todo o método de Deque), no entanto, usa a estrutura de dados da matriz. Quanto a qual é o melhor, depende de como e onde você os usa.
fonte
Nem sempre é esse o caso.
Por exemplo, no caso abaixo
linkedlist
, o desempenho é melhor que oArrayDeque
do leetcode 103.fonte
A complexidade de tempo para ArrayDeque para acessar um elemento é O (1) e para LinkList é O (N) para acessar o último elemento. O ArrayDeque não é seguro para threads, sendo necessária a sincronização manual para que você possa acessá-lo através de vários threads e para que sejam mais rápidos.
fonte
LinkedList
JavaCollection
, ele é duplamente vinculado e tem acesso rápido à cabeça e à cauda, portanto, o acesso ao último elemento também leva O (1).