Estoy tratando de entender por qué ArrayDeque de Java es mejor que LinkedList de Java, ya que ambos implementan la interfaz Deque.
Apenas veo a alguien usando ArrayDeque en su código. Si alguien arroja más luz sobre cómo se implementa ArrayDeque, sería útil.
Si lo entiendo, estaré más seguro de usarlo. No podía entender claramente la implementación de JDK en cuanto a la forma en que maneja las referencias de cabeza y cola.
java
deque
linked-list
arraydeque
Cruel
fuente
fuente
src.zip
. Es el archivo con el código fuente de las clases de Java. Recomiendo estudiar la estructura de estas clases y las partes internas para comprender mejor cómo funcionan las clases de Java.Respuestas:
Las estructuras vinculadas son posiblemente la peor estructura para iterar con una falta de caché en cada elemento. Además, consumen mucha más memoria.
Si necesita agregar / quitar ambos extremos, ArrayDeque es significativamente mejor que una lista vinculada. El acceso aleatorio de cada elemento también es O (1) para una cola cíclica.
La única mejor operación de una lista vinculada es eliminar el elemento actual durante la iteración.
fuente
LinkedList
implementaList
mientrasArrayDeque
que no. Esto significa queLinkedList
tienen métodos comoindexOf
oremove(int)
mientras queArrayDeque
no. Puede ser importante a veces.Creo que el principal cuello de botella en el rendimiento
LinkedList
es el hecho de que cada vez que avanza hacia cualquier extremo de la deque, detrás de escena, la implementación asigna un nuevo nodo de lista vinculada, que esencialmente involucra JVM / OS, y eso es costoso. Además, cada vez que aparece desde cualquier extremo, los nodos internos seLinkedList
vuelven elegibles para la recolección de basura y eso es más trabajo detrás de escena. Además, dado que los nodos de la lista vinculada se asignan aquí y allá, el uso de la memoria caché de la CPU no proporcionará muchos beneficios.Si puede ser de interés, tengo una prueba de que agregar (agregar) un elemento
ArrayList
oArrayDeque
ejecuta en tiempo constante amortizado; refiérase a esto .fuente
ArrayDeque
es nuevo con Java 6, por lo que una gran cantidad de código (especialmente proyectos que intentan ser compatibles con versiones anteriores de Java) no lo usan.Es "mejor" en algunos casos porque no está asignando un nodo para cada elemento para insertar; en cambio, todos los elementos se almacenan en una matriz gigante, que se redimensiona si se llena.
fuente
Es probable que todas las personas que critican a
LinkedList
, piensen en todos los demás tipos que han estado usandoList
en Java,ArrayList
y laLinkedList
mayoría de las veces porque han estado antes de Java 6 y porque esos son los que se enseñan como comienzo en la mayoría de los libros.Sin embargo, eso no quiere decir, me gustaría tener a ciegas
LinkedList
's oArrayDeque
' lado s. Si quieres saber, echa un vistazo al siguiente punto de referencia realizado por Brian .La configuración de prueba considera:
Resultado de la prueba:
Grafico:
Para llevar:
ArrayList
oArrayDeque
con una buena estimación de la capacidad máxima que puede requerir la lista debido a la estricta restricción de memoria.LinkedList
banda de rodadura con mucho cuidado al decidir usar un,ArrayDeque
especialmente porque NO implementa laList
interfaz (creo que esa es una razón lo suficientemente grande). Es posible que su base de código se comunique ampliamente con la interfaz de la Lista, lo más probable es que decida saltar con unArrayDeque
. Usarlo para implementaciones internas podría ser una buena idea ...fuente
ArrayDeque y LinkedList están implementando la interfaz Deque , pero la implementación es diferente.
Diferencias clave
La clase ArrayDeque es la implementación de matriz redimensionable de la interfaz Deque y la clase LinkedList es la implementación de la lista
Se pueden agregar elementos NULL a LinkedList pero no en ArrayDeque
ArrayDeque es más eficiente que LinkedList para agregar y quitar operaciones en ambos extremos y la implementación de LinkedList es eficiente para eliminar el elemento actual durante la iteración
La implementación de LinkedList consume más memoria que ArrayDeque
Entonces, si no tiene que admitir elementos NULL && buscando menos memoria && eficiencia de agregar / eliminar elementos en ambos extremos, ArrayDeque es el mejor
Consulte la documentación para más detalles.
fuente
header.previous.element
). El reclamo de "eficiencia de memoria" también puede ser cuestionado ya que la matriz de respaldo siempre cambia de tamaño a la siguiente potencia de 2.Iterator
para acceder al último elemento, la operación es O (N) para ambas clases. Cuando usa laDeque
interfaz común , el acceso al último elemento es O (1) para ambas clases. Independientemente del punto de vista que adopte, atribuir O (1)ArrayDeque
y O (N) alLinkedList
mismo tiempo es incorrecto.aunque
ArrayDeque<E>
yLinkedList<E>
ambos han implementado laDeque<E>
interfaz, pero ArrayDeque usa básicamente una matriz de objetosE[]
para mantener los elementos dentro de su objeto, por lo que generalmente usa el índice para ubicar los elementos de cabeza y cola.En una palabra, simplemente funciona como Deque (con todos los métodos de Deque), pero usa la estructura de datos de la matriz. En cuanto a cuál es mejor, depende de cómo y dónde los use.
fuente
Ese no es siempre el caso.
Por ejemplo, en el caso a continuación
linkedlist
tiene un mejor rendimiento que deArrayDeque
acuerdo con leetcode 103.fuente
La complejidad de tiempo para ArrayDeque para acceder a un elemento es O (1) y para LinkList es O (N) para acceder al último elemento. ArrayDeque no es seguro para subprocesos, por lo que la sincronización manual es necesaria para que pueda acceder a través de múltiples subprocesos y que sean más rápidos.
fuente
LinkedList
JavaCollection
, está doblemente vinculado y tiene acceso rápido a la cabeza y la cola, por lo que el acceso al último elemento también requiere O (1).