J'essaie de comprendre pourquoi ArrayDeque de Java est meilleur que LinkedList de Java car ils implémentent tous les deux l'interface Deque.
Je vois à peine quelqu'un utiliser ArrayDeque dans son code. Si quelqu'un met plus de lumière sur la manière dont ArrayDeque est implémenté, ce serait utile.
Si je le comprends, je serai plus confiant de l'utiliser. Je ne pouvais pas comprendre clairement l'implémentation JDK quant à la façon dont elle gère les références tête et queue.
java
deque
linked-list
arraydeque
Cruel
la source
la source
src.zip
. C'est l'archive avec le code source des classes java. Je recommande fortement d'étudier la structure et les éléments internes de ces classes pour mieux comprendre le fonctionnement des classes Java.Réponses:
Les structures liées sont probablement la pire structure à itérer avec un cache manquant sur chaque élément. De plus, ils consomment beaucoup plus de mémoire.
Si vous avez besoin d'ajouter / supprimer les deux extrémités, ArrayDeque est nettement meilleur qu'une liste liée. L'accès aléatoire à chaque élément est également O (1) pour une file d'attente cyclique.
La seule meilleure opération d'une liste chaînée est de supprimer l'élément actuel pendant l'itération.
la source
LinkedList
implémenteList
tandisArrayDeque
que non. Cela signifie que vousLinkedList
avez des méthodes commeindexOf
ouremove(int)
pendant queArrayDeque
non. Cela peut parfois être important.Je pense que le principal goulot d'étranglement des performances
LinkedList
réside dans le fait que chaque fois que vous poussez à n'importe quelle extrémité du deque, dans les coulisses, la mise en œuvre alloue un nouveau nœud de liste chaînée, qui implique essentiellement JVM / OS, et c'est cher. De plus, chaque fois que vous sortez de n'importe quelle extrémité, les nœuds internesLinkedList
deviennent éligibles pour le garbage collection et c'est plus de travail en arrière-plan. De plus, étant donné que les nœuds de la liste liée sont alloués ici et là, l'utilisation du cache du processeur ne fournira pas beaucoup d'avantages.Si cela peut être intéressant, j'ai une preuve que l'ajout (ajout) d'un élément à
ArrayList
ouArrayDeque
s'exécute en temps constant amorti; référez-vous à cela .la source
ArrayDeque
est nouveau avec Java 6, c'est pourquoi beaucoup de code (en particulier les projets qui essaient d'être compatibles avec les versions précédentes de Java) ne l'utilisent pas.C'est «mieux» dans certains cas parce que vous n'allouez pas de nœud pour chaque élément à insérer; au lieu de cela, tous les éléments sont stockés dans un tableau géant, qui est redimensionné s'il est plein.
la source
Tous les gens qui critiquent un
LinkedList
, pensent à tous les autres gars qui ont utiliséList
en Java utilisent probablementArrayList
et laLinkedList
plupart du temps parce qu'ils ont été avant Java 6 et parce que ce sont ceux qui sont enseignés comme un début dans la plupart des livres.Mais, cela ne veut pas dire, je prendrais aveuglément
LinkedList
« ou deArrayDeque
» côté s. Si vous voulez savoir, jetez un œil au benchmark ci-dessous réalisé par Brian .La configuration du test prend en compte:
Résultat du test:
Graphique:
À emporter:
ArrayList
ouArrayDeque
avec une bonne estimation de la capacité maximale que la liste peut être requise en raison d'une contrainte de mémoire stricte.LinkedList
bande de roulement tellement prudente au moment de décider d'utiliser un, enArrayDeque
particulier parce qu'il n'implémente PAS l'List
interface (je pense que c'est une raison assez grande). Il se peut que votre base de code communique beaucoup avec l'interface List, très probablement et que vous décidez de vous lancer avec unArrayDeque
. L'utiliser pour des implémentations internes pourrait être une bonne idée ...la source
ArrayDeque et LinkedList implémentent Deque interface mais l'implémentation est différente.
Principales différences:
La classe ArrayDeque est l'implémentation de tableau redimensionnable de l' interface Deque et la classe LinkedList est l'implémentation de la liste
Les éléments NULL peuvent être ajoutés à LinkedList mais pas dans ArrayDeque
ArrayDeque est plus efficace que LinkedList pour l'opération d'ajout et de suppression aux deux extrémités et l'implémentation de LinkedList est efficace pour supprimer l'élément actuel pendant l'itération
L' implémentation LinkedList consomme plus de mémoire que ArrayDeque
Donc, si vous n'avez pas à prendre en charge les éléments NULL && à la recherche de moins de mémoire && efficacité d'ajout / suppression d'éléments aux deux extrémités, ArrayDeque est le meilleur
Reportez-vous à la documentation pour plus de détails.
la source
header.previous.element
). L'affirmation "efficacité de la mémoire" peut également être contestée puisque le tableau de support est toujours redimensionné à la prochaine puissance de 2.Iterator
pour accéder au dernier élément, l'opération est O (N) pour les deux classes. Lorsque vous utilisez l'Deque
interface commune , l'accès au dernier élément est O (1) pour les deux classes. Quel que soit le point de vue que vous adoptez, attribuer O (1) àArrayDeque
et O (N) enLinkedList
même temps est faux.bien que
ArrayDeque<E>
etLinkedList<E>
ont tous deux implémentéDeque<E>
Interface, mais ArrayDeque utilise essentiellement un tableau ObjectE[]
pour garder les éléments à l'intérieur de son Object, donc il utilise généralement un index pour localiser les éléments head et tail.En un mot, cela fonctionne comme Deque (avec toute la méthode Deque), mais utilise la structure de données du tableau. Quant à savoir lequel est le meilleur, cela dépend comment et où vous les utilisez.
la source
Ce n'est pas toujours le cas.
Par exemple, dans le cas ci-dessous
linkedlist
a de meilleures performances queArrayDeque
selon le leetcode 103.la source
La complexité temporelle pour ArrayDeque pour accéder à un élément est O (1) et celle pour LinkList est O (N) pour accéder au dernier élément. ArrayDeque n'est pas thread-safe, donc une synchronisation manuelle est nécessaire pour que vous puissiez y accéder via plusieurs threads et qu'ils soient plus rapides.
la source
LinkedList
JavaCollection
, il est doublement lié et a un accès rapide à la tête et à la queue, donc l'accès au dernier élément prend également O (1).