Base de la colección JAVA (1)

I. Introducción

A. ¿Qué es un conjunto?

        Collection (Colección) es un contenedor para almacenar y manipular un conjunto de objetos en el lenguaje de programación Java. Es la parte central del marco de recopilación de Java, que proporciona un conjunto de interfaces y clases para procesar diferentes tipos de datos de recopilación.

        En programación, a menudo necesitamos tratar con un grupo de objetos relacionados, como almacenar listas de usuarios, información de productos, registros, etc. Las colecciones brindan una forma conveniente de organizar y manipular estos objetos, lo que nos permite agregar, eliminar, buscar, ordenar, etc., así como interactuar y convertir fácilmente entre colecciones.

        El marco de la colección proporciona varios tipos de clases de colección, cada una de las cuales tiene sus propias características y escenarios aplicables. Las clases de colección comunes incluyen List (lista), Set (colección), Map (mapeo) y Queue (cola). Pueden almacenar diferentes tipos de objetos y tener diferentes propiedades y características de rendimiento.

        El uso de colecciones puede ayudarnos a mejorar la legibilidad, la flexibilidad y la capacidad de mantenimiento de nuestro código. Proporcionan una serie de métodos y algoritmos que nos permiten operar y procesar fácilmente los elementos de la colección. Además, las colecciones también brindan algunas funciones convenientes, como recorrer colecciones, filtrar elementos, ordenar y buscar, etc.

        En definitiva, una colección es un contenedor para almacenar y manipular un grupo de objetos, lo que proporciona una gran cantidad de funciones y métodos para organizar y procesar datos. Mediante el uso de colecciones, podemos tratar varios problemas de algoritmos y estructuras de datos de manera más eficiente y flexible.

B. Por qué usar colecciones

  1. Organización y administración de datos: las colecciones brindan una manera conveniente de organizar y administrar un grupo de objetos de datos relacionados. Nos permiten agrupar objetos de manera lógicamente relacionada, formando colecciones de datos más estructuradas. Con las colecciones, podemos representar y manipular datos con mayor claridad, lo que hace que el código sea más legible y mantenible.

  2. Rico en funciones: el marco de la colección proporciona muchos métodos y algoritmos integrados, lo que nos permite realizar operaciones comunes en las colecciones de manera conveniente, como agregar, eliminar, buscar, ordenar y atravesar. Estas características simplifican enormemente el trabajo con colecciones, ahorrando tiempo y esfuerzo al escribir código repetitivo.

  3. Escalabilidad y flexibilidad: las colecciones proporcionan múltiples tipos de clases de colección, cada una con diferentes características y escenarios aplicables. Esto nos permite elegir la clase de colección más adecuada en función de nuestras necesidades y ampliar y personalizar la colección según sea necesario. La flexibilidad de las colecciones nos permite adaptarnos a diferentes necesidades comerciales y estructuras de datos, y lidiar con varios algoritmos y problemas complejos.

  4. Rendimiento mejorado: las diversas clases de colección en el marco de colecciones se han optimizado y ajustado para proporcionar un almacenamiento y acceso de datos eficientes. Por ejemplo, ArrayList proporciona un acceso aleatorio rápido, LinkedList proporciona operaciones de inserción y eliminación eficientes, HashMap proporciona una búsqueda rápida de pares clave-valor, etc. Al elegir la clase de colección adecuada, podemos mejorar el rendimiento y la eficiencia del programa.

  5. Estructura de datos y soporte de algoritmos: el marco de recopilación proporciona una variedad de estructuras de datos y soporte de algoritmos de uso común, como listas, colecciones, mapas, colas, etc. Estas estructuras de datos y algoritmos son la base para resolver muchos problemas de programación. Mediante el uso de colecciones, podemos implementar y aplicar más fácilmente estas estructuras de datos y algoritmos, mejorando la calidad y la mantenibilidad del código.

        En general, el uso de colecciones puede simplificar la organización y gestión de datos, proporcionar funciones y métodos ricos, tener escalabilidad y flexibilidad, y puede mejorar el rendimiento y la eficiencia de los programas. Al elegir y usar colecciones de manera razonable, podemos manejar y resolver mejor varios problemas de estructura de datos y algoritmos.

II. Descripción general del marco de colecciones de Java

A. Arquitectura del marco de las colecciones

La arquitectura del marco de la colección Java se basa en el núcleo de la interfaz, que incluye principalmente las siguientes interfaces y clases clave:

  1. Interfaz de colección: la interfaz de colección es la interfaz raíz del marco de colección, que define métodos comunes para operar en un conjunto de objetos. Deriva subinterfaces de uso común, como List, Set y Queue.

  2. Interfaz de lista: la interfaz de lista hereda de la interfaz de colección y representa una colección ordenada de elementos, que puede contener elementos repetidos. Las clases de implementación comunes de la interfaz List incluyen ArrayList, LinkedList y Vector.

  3. Interfaz de conjunto: la interfaz de conjunto hereda de la interfaz de colección y representa una colección desordenada de elementos, y no se permiten elementos duplicados. Las clases de implementación comunes de la interfaz Set incluyen HashSet, TreeSet y LinkedHashSet.

  4. Interfaz de cola: la interfaz de cola se hereda de la interfaz de colección, que representa la estructura de datos de la cola y admite la adición de elementos al final de la cola y la eliminación de elementos del principio de la cola. Las clases de implementación comunes de la interfaz Queue incluyen ArrayDeque y PriorityQueue.

  5. Interfaz de mapa: la interfaz de mapa es una colección de pares clave-valor utilizados para almacenar un conjunto de claves únicas y valores correspondientes. La clase de implementación de la interfaz Map permite que tanto la clave como el valor sean nulos, pero la clave debe ser única. Las clases de implementación comunes incluyen HashMap, TreeMap y LinkedHashMap.

        En el marco de la colección, hay algunas otras interfaces y clases para ampliar y mejorar las funciones de la colección, como la interfaz Iterator para atravesar los elementos de la colección, la interfaz Comparable para ordenar, la interfaz Comparator para comparadores personalizados, etc.

        El diseño del marco de la colección sigue algunos principios de diseño, como el principio de aislamiento de interfaz, el principio de responsabilidad única y el principio de apertura y cierre, que hacen que la clase de colección sea altamente escalable y flexible. Mediante el uso de estas interfaces y clases, podemos seleccionar y combinar fácilmente diferentes tipos de colecciones para satisfacer diferentes necesidades comerciales y requisitos de algoritmos.

B. Introducción a las interfaces y clases principales

1. Interfaz de colección y su clase de implementación

        La interfaz de colección es una de las interfaces raíz del marco de colección de Java, que define un conjunto de métodos comunes para manipular un conjunto de objetos. Es la interfaz principal de todas las clases de colección y proporciona algunas operaciones básicas de colección, como agregar, eliminar, atravesar, etc. La siguiente es una introducción a las clases de implementación de algunas interfaces de colección comunes:

  1. Lista de arreglo:

    • ArrayList es una matriz dinámica basada en matrices, que se puede expandir automáticamente según sea necesario.
    • Permite acceso aleatorio a elementos, acceso rápido y modificación de elementos mediante indexación.
    • Es adecuado para escenarios en los que se accede a los elementos y se modifican con frecuencia.
  2. Lista enlazada:

    • LinkedList es una lista doblemente enlazada implementada basada en una lista enlazada.
    • Permite la inserción y eliminación eficiente de elementos al principio y al final de la colección.
    • Es adecuado para escenarios donde los elementos se insertan y eliminan con frecuencia.
  3. HashSet:

    • HashSet se implementa en base a una tabla hash, que utiliza un algoritmo hash para almacenar y recuperar elementos.
    • No garantiza el orden de los elementos y no permite elementos duplicados.
    • Es adecuado para escenarios en los que necesita encontrar elementos rápidamente y no se preocupa por el orden.
  4. Conjunto de árboles:

    • TreeSet se implementa en base a un árbol rojo-negro, que ordena y almacena elementos.
    • Mantiene el orden de clasificación de los elementos y no permite elementos duplicados.
    • Adecuado para escenarios que requieren colecciones ordenadas.
  5. Conjunto de hash vinculado:

    • LinkedHashSet es una subclase de HashSet, que se implementa mediante una tabla hash y una lista vinculada.
    • Mantiene el orden de inserción de los elementos y no permite elementos duplicados.
    • Adecuado para escenarios en los que es necesario mantener el orden de inserción.
  6. Cola de prioridad:

    • PriorityQueue es una cola implementada en función de un montón de prioridad.
    • Ordena los elementos según su prioridad, y al obtener un elemento devuelve el elemento con la prioridad más alta.
    • Aplicable a escenarios que requieren procesamiento de elementos según prioridad.

        Las anteriores son algunas clases de implementación comunes de la interfaz Collection, y cada clase de implementación tiene sus propias características y escenarios aplicables. La elección de una clase de implementación adecuada depende de requisitos y operaciones específicos, como requisitos de orden, frecuencia de inserción/eliminación, manejo de elementos repetidos, etc.

2. Interfaz del mapa y su clase de implementación

        La interfaz Map es una interfaz utilizada para almacenar pares clave-valor en el marco de colección de Java y proporciona un conjunto de métodos para manipular pares clave-valor. La siguiente es una introducción a algunas clases de implementación comunes de la interfaz Map:

  1. Mapa hash:

    • HashMap es un mapa implementado en base a una tabla hash, que utiliza un algoritmo hash para almacenar y recuperar pares clave-valor.
    • No garantiza el orden de los pares clave-valor, permitiendo valores nulos como claves y valores.
    • Es adecuado para escenarios que necesitan encontrar rápidamente pares clave-valor y no se preocupan por el orden.
  2. Mapa de árbol:

    • TreeMap se implementa en base a un árbol rojo-negro, que almacena claves en orden ordenado.
    • Mantiene el orden de clasificación de las claves, permitiendo valores nulos.
    • Aplicable a escenarios que requieren pares clave-valor ordenados.
  3. LinkedHashMap:

    • LinkedHashMap es una subclase de HashMap, que se implementa a través de una tabla hash y una lista doblemente enlazada.
    • Mantiene el orden de inserción u orden de acceso (opcional), permitiendo valores nulos como claves y valores.
    • Adecuado para escenarios en los que es necesario mantener el orden de inserción o de acceso.
  4. Tabla de picadillo:

    • Hashtable es una clase de implementación de mapa segura para subprocesos, similar a HashMap.
    • No garantiza el orden de los pares clave-valor y no permite valores nulos como clave y valor.
    • Es adecuado para escenarios que requieren seguridad de subprocesos en un entorno de subprocesos múltiples.
  5. Mapa hash concurrente:

    • ConcurrentHashMap es una clase de implementación de mapa eficiente y segura para subprocesos.
    • Utiliza un mecanismo de bloqueo segmentado para la seguridad de subprocesos, lo que permite lecturas y escrituras simultáneas.
    • Es adecuado para escenarios que requieren alto rendimiento y seguridad de subprocesos en un entorno de alta concurrencia.

        Las anteriores son algunas clases de implementación comunes de la interfaz Map, y cada clase de implementación tiene sus propias características y escenarios aplicables. La elección de una clase de implementación adecuada depende de los requisitos y operaciones específicos, como los requisitos de orden para los pares clave-valor, los requisitos para la seguridad de subprocesos, la compatibilidad con valores nulos, etc.

III. Características y escenarios aplicables de las clases de colección comúnmente utilizadas

Una lista

1. ArrayLista

ArrayList es la clase de implementación de la interfaz List en el marco de colección de Java, se implementa en base a un arreglo y tiene las siguientes características:

  1. Matriz dinámica: la implementación subyacente de ArrayList es una matriz de longitud variable que se puede expandir automáticamente según sea necesario. Cuando la cantidad de elementos excede la capacidad actual, ArrayList aumentará automáticamente la capacidad para acomodar más elementos.

  2. Acceso aleatorio: dado que la capa inferior se implementa en base a matrices, ArrayList admite el acceso rápido y la modificación de elementos a través de índices. Se puede acceder directamente al elemento en la posición especificada de acuerdo con el índice, y la complejidad de tiempo es O(1).

  3. Permitir elementos repetidos: ArrayList permite almacenar elementos repetidos, y el mismo elemento puede aparecer varias veces.

  4. No seguro para subprocesos: ArrayList no es seguro para subprocesos y no es adecuado para el acceso simultáneo en un entorno de subprocesos múltiples. Si necesita usarlo en un entorno de subprocesos múltiples, considere usar una clase alternativa segura para subprocesos, como CopyOnWriteArrayList o Vector.

  5. Adecuado para acceder y modificar elementos con frecuencia: debido a que admite el acceso aleatorio y la modificación de elementos, ArrayList funciona bien en escenarios en los que es necesario buscar, recorrer y modificar elementos con frecuencia.

Según las características anteriores, ArrayList es adecuado para los siguientes escenarios:

  1. Necesita acceder a los elementos de forma aleatoria: ArrayList es una buena opción si necesita acceder rápidamente a los elementos de la colección por índice.

  2. Los elementos deben modificarse con frecuencia: dado que la capa inferior de ArrayList se implementa en función de las matrices, las operaciones de inserción, eliminación y modificación de los elementos son más eficientes y son adecuadas para escenarios en los que los elementos se modifican con frecuencia.

  3. El número de elementos es variable: cuando el número de elementos de la colección cambia dinámicamente, el mecanismo de expansión dinámica de ArrayList puede adaptarse automáticamente al aumento o disminución de elementos sin ajustar manualmente la capacidad.

  4. No implica operaciones concurrentes de subprocesos múltiples: si se trata de un entorno de subproceso único, o para garantizar que las operaciones de acceso en un entorno de subprocesos múltiples estén sincronizadas, ArrayList puede cumplir con los requisitos.

        Debe tenerse en cuenta que si las operaciones de inserción y eliminación de elementos son frecuentes y la colección es grande, puede causar copias frecuentes de la matriz y afectar el rendimiento. En este caso, puede considerar usar LinkedList como alternativa, que tiene un mejor rendimiento en las operaciones de inserción y eliminación, pero un acceso aleatorio menos eficiente.

2. Lista Vinculada

LinkedList es otra clase de implementación de la interfaz List en el marco de la colección Java, se implementa en base a una lista enlazada y tiene las siguientes características:

  1. Estructura de lista enlazada: LinkedList almacena elementos en forma de una lista doblemente enlazada, y cada nodo contiene referencias al nodo anterior y al nodo siguiente. En comparación con ArrayList basado en la implementación de matrices, las operaciones de inserción y eliminación de LinkedList son más eficientes.

  2. Alta eficiencia de inserción y eliminación: Debido a las características de la lista enlazada, solo se necesita modificar la referencia del nodo al insertar y eliminar elementos, y no es necesario expandir la matriz o copiar datos. Por lo tanto, LinkedList funciona mejor en escenarios que requieren la inserción y eliminación frecuente de elementos.

  3. No admite el acceso aleatorio: LinkedList no admite el acceso directo a los elementos a través de índices, sino que debe atravesar desde el principio o el final de la lista vinculada. Por lo tanto, la eficiencia del acceso aleatorio es baja y la complejidad temporal es O(n).

  4. Permite almacenar elementos duplicados: Al igual que ArrayList, LinkedList también permite almacenar elementos duplicados.

  5. No seguro para subprocesos: LinkedList no es seguro para subprocesos y no es adecuado para el acceso simultáneo en un entorno de subprocesos múltiples. Si necesita usarlo en un entorno de subprocesos múltiples, considere usar una clase alternativa segura para subprocesos, como CopyOnWriteArrayList o Vector.

Según las características anteriores, LinkedList es adecuado para los siguientes escenarios:

  1. Inserción y eliminación frecuente de elementos: debido a la alta eficiencia de las operaciones de inserción y eliminación de LinkedList, es adecuado para escenarios que requieren la inserción y eliminación frecuente de elementos.

  2. Es necesario implementar colas o pilas: debido a las características estructurales de las listas enlazadas, LinkedList puede implementar fácilmente la estructura de datos de colas (FIFO) o pilas (LIFO).

  3. Acceso secuencial o inverso a elementos: LinkedList proporciona métodos para obtener el primer elemento, el último elemento y el recorrido secuencial o inverso de elementos, adecuado para escenarios que requieren acceso secuencial o inverso a elementos.

  4. No implica operaciones concurrentes de subprocesos múltiples: si se trata de un entorno de un solo subproceso, o para garantizar que las operaciones de acceso en un entorno de subprocesos múltiples estén sincronizadas, LinkedList puede cumplir con los requisitos.

        Cabe señalar que, dado que LinkedList no admite el acceso aleatorio, puede ser más apropiado usar ArrayList para escenarios que requieren un acceso frecuente basado en índices. Además, LinkedList tiene un ligero aumento en el uso de memoria en comparación con ArrayList debido a la necesidad de espacio de memoria adicional para almacenar referencias de nodos.

3. Vectores

Vector es otra clase de implementación de la interfaz List en el marco de colección de Java.Es similar a ArrayList, pero tiene las siguientes características:

  1. Seguridad de subprocesos: Vector es seguro para subprocesos y garantiza la seguridad de subprocesos al agregar bloqueos de sincronización en cada método. Múltiples subprocesos pueden operar en Vector al mismo tiempo sin inconsistencia de datos.

  2. Matriz dinámica: la implementación subyacente de Vector también se basa en matrices, similar a ArrayList, tiene la función de expansión automática. Cuando la cantidad de elementos exceda la capacidad actual, Vector aumentará automáticamente la capacidad para acomodar más elementos.

  3. Permitir elementos repetidos: Vector permite almacenar elementos repetidos, y el mismo elemento puede aparecer varias veces.

  4. Relativamente ineficiente: dado que Vector es seguro para subprocesos, debe realizar operaciones de sincronización en cada método, lo que generará una sobrecarga de rendimiento adicional. En comparación con ArrayList, el rendimiento de Vector puede ser ligeramente inferior en un entorno de subproceso único.

En base a las características anteriores, Vector es adecuado para los siguientes escenarios:

  1. Entorno de subprocesos múltiples: dado que Vector es seguro para subprocesos, es adecuado para escenarios que requieren acceso y modificación simultáneos de colecciones en un entorno de subprocesos múltiples. Múltiples subprocesos pueden operar en Vector al mismo tiempo sin medidas de sincronización adicionales.

  2. Colecciones que necesitan crecer dinámicamente: si la cantidad de elementos en la colección cambia dinámicamente y necesita operarse en un entorno de subprocesos múltiples, Vector puede expandirse automáticamente y garantizar la seguridad de los subprocesos.

  3. Permite almacenar elementos repetidos: si necesita almacenar elementos repetidos, Vector es una opción opcional.

        Cabe señalar que debido a la operación síncrona de Vector en todos los métodos, es relativamente bajo en términos de rendimiento. En un entorno de subproceso único, si no necesita operaciones seguras para subprocesos, puede considerar usar ArrayList como alternativa. Además, Java 1.2 introdujo clases seguras para subprocesos más eficientes, como CopyOnWriteArrayList y ConcurrentLinkedDeque, que pueden ser más adecuadas para su uso en escenarios de alta concurrencia.

B conjunto

1. HashSet

HashSet es la clase de implementación de la interfaz Set en el marco de la colección Java, que tiene las siguientes características:

  1. Basado en una tabla hash: la implementación subyacente de HashSet se basa en una tabla hash (HashMap), que utiliza un algoritmo hash para almacenar y recuperar elementos. Cada elemento se almacena como parte de la clave, mientras que el valor es un marcador de posición fijo.

  2. No se permiten elementos duplicados: HashSet no permite almacenar elementos duplicados. Si intenta agregar elementos duplicados al HashSet, se ignorará.

  3. Colección desordenada: los elementos en HashSet no tienen un orden fijo, es decir, el orden de almacenamiento y recorrido de los elementos es impredecible.

  4. Inserción y búsqueda eficientes: dado que HashSet se implementa en función de una tabla hash, la complejidad temporal de las operaciones de inserción y búsqueda es O(1). Esto hace que HashSet funcione bien en escenarios de inserción y búsqueda de grandes cantidades de datos.

  5. No es seguro para subprocesos: HashSet no es seguro para subprocesos. Si se requiere acceso simultáneo a HashSet en un entorno de subprocesos múltiples, se requiere un control de sincronización externo.

Según las características anteriores, HashSet es adecuado para los siguientes escenarios:

  1. Almacenamiento de deduplicación: dado que HashSet no permite el almacenamiento de elementos duplicados, a menudo se usa para operaciones de deduplicación. Los elementos que deben desduplicarse se pueden agregar al HashSet para lograr una desduplicación rápida.

  2. Encuentre y determine si existe un elemento: debido a la función de búsqueda eficiente de HashSet, se puede usar para determinar rápidamente si existe un elemento en el conjunto. El método contains() de HashSet puede determinar rápidamente si un elemento existe sin recorrer toda la colección.

  3. Almacene elementos que no requieran un orden fijo: si no necesita mantener un orden específico de elementos, sino que solo se preocupa por la singularidad de los elementos y la inserción y búsqueda eficientes, HashSet es una opción adecuada.

        Cabe señalar que dado que HashSet se implementa en base a una tabla hash, su orden de elementos es impredecible. Si necesita almacenar elementos de manera ordenada, puede considerar usar LinkedHashSet, que mantiene el orden de inserción de los elementos en función de HashSet.

2. Conjunto de árboles

TreeSet es la clase de implementación de la interfaz Set en el marco de la colección Java y tiene las siguientes características:

  1. Basado en el árbol rojo-negro: la implementación subyacente de TreeSet se basa en la estructura de datos del árbol rojo-negro. Un árbol rojo-negro es un árbol de búsqueda binario autoequilibrado que mantiene el orden de los elementos y proporciona operaciones eficientes de inserción, eliminación y búsqueda.

  2. Colección ordenada: los elementos del TreeSet están ordenados, clasificados de acuerdo con la clasificación natural de los elementos o las reglas de clasificación personalizadas. Por defecto, un TreeSet se ordena según el orden natural de los elementos, o según el comparador pasado.

  3. No se permiten elementos duplicados: TreeSet no permite almacenar elementos duplicados. Se ignorarán los intentos de agregar elementos duplicados al TreeSet.

  4. Inserción, eliminación y búsqueda eficientes: dado que la capa inferior de TreeSet es un árbol rojo-negro, la complejidad temporal de las operaciones de inserción, eliminación y búsqueda es O (log n). Esto hace que TreeSet funcione bien en escenarios de almacenamiento y recuperación de colecciones ordenadas.

  5. No es seguro para subprocesos: TreeSet no es seguro para subprocesos. Si necesita acceder a TreeSet simultáneamente en un entorno de subprocesos múltiples, debe realizar un control de sincronización externo.

En base a las características anteriores, TreeSet es adecuado para los siguientes escenarios:

  1. Almacenamiento ordenado: dado que TreeSet está ordenado, a menudo se usa en escenarios donde los elementos deben almacenarse en un orden determinado. Los elementos se pueden almacenar en un orden específico según su orden natural o un comparador personalizado.

  2. Búsqueda por rango: dado que TreeSet está ordenado, es muy conveniente realizar una búsqueda por rango. El subconjunto dentro del rango especificado se puede obtener mediante el método subSet() de TreeSet.

  3. Almacene los elementos que deben ordenarse: si necesita almacenar un conjunto de elementos y ordenarlos, TreeSet es una opción adecuada.

        Cabe señalar que, dado que TreeSet se implementa en función de un árbol rojo-negro, tiene un alto rendimiento para las operaciones de inserción, eliminación y búsqueda. Pero en comparación con HashSet, tiene una mayor huella de memoria porque cada elemento requiere espacio de almacenamiento adicional para mantener la estructura de árbol. Además, la clasificación de los elementos puede agregar cierta cantidad de tiempo de sobrecarga, especialmente en el caso de intercalaciones personalizadas. Por lo tanto, en escenarios con requisitos de alto rendimiento, es necesario evaluar cuidadosamente si elegir TreeSet.

3. Conjunto de hash vinculado

LinkedHashSet es la clase de implementación de la interfaz Set en el marco de colección de Java, es una subclase de HashSet, tiene las características de HashSet y además mantiene el orden de inserción de los elementos. Las siguientes son las características y escenarios aplicables de LinkedHashSet:

  1. Mantener el orden de inserción: LinkedHashSet utiliza internamente una lista doblemente enlazada para mantener el orden de inserción de los elementos. Por lo tanto, al atravesar el LinkedHashSet, el orden de los elementos es consistente con el orden de inserción.

  2. No se permiten elementos duplicados: al igual que HashSet, LinkedHashSet no permite almacenar elementos duplicados. Si intenta agregar elementos duplicados a LinkedHashSet, se ignorará.

  3. Basado en una tabla hash: la implementación subyacente de LinkedHashSet todavía se basa en una tabla hash (HashMap). Además de usar una tabla hash para almacenar elementos, también se usa una lista enlazada para mantener el orden de inserción de los elementos.

  4. Colección ordenada: Dado que LinkedHashSet mantiene el orden de inserción de los elementos, se ordena. El orden de recorrido de los elementos es coherente con el orden de inserción.

  5. Rendimiento ligeramente inferior al de HashSet: dado que LinkedHashSet necesita mantener una estructura de lista enlazada adicional para mantener el orden de inserción, su rendimiento en las operaciones de inserción y eliminación es ligeramente inferior al de HashSet. Pero en comparación con ArrayList y LinkedList, LinkedHashSet tiene un mayor rendimiento en las operaciones de búsqueda.

Según las características anteriores, LinkedHashSet es adecuado para los siguientes escenarios:

  1. Necesidad de mantener el orden de inserción de los elementos: si necesita almacenar y recorrer elementos en el orden de inserción, LinkedHashSet es una opción adecuada.

  2. Deduplicar el almacenamiento y mantener el orden de inserción: dado que LinkedHashSet no permite almacenar elementos duplicados y mantiene el orden de inserción, se puede usar para el almacenamiento de deduplicación y mantiene el orden en que se agregan los elementos.

  3. Estrategia Cached LRU (Least Recent Used): Dado que LinkedHashSet mantiene el orden de inserción, se puede utilizar para implementar una caché basada en la estrategia LRU, es decir, la estrategia menos utilizada. Cuando la memoria caché se queda sin espacio, se puede eliminar el elemento al que no se ha accedido durante más tiempo.

        Cabe señalar que LinkedHashSet ocupará más espacio de memoria mientras mantiene el orden de inserción de los elementos, porque se debe mantener una estructura de lista vinculada adicional. Por lo tanto, en escenarios con altos requisitos de uso de memoria, debe elegir con cuidado.

C Mapa

1. Mapa hash

HashMap es una clase de implementación de la interfaz Map en el marco de la colección Java y tiene las siguientes características:

  1. Almacenamiento de pares clave-valor: HashMap es una estructura de almacenamiento basada en pares clave-valor (clave-valor), y cada elemento consta de una clave y un valor. Los valores se identifican de forma única y se accede a ellos mediante claves.

  2. Basado en Hash Table: La implementación subyacente de HashMap se basa en Hash Table. Las tablas hash utilizan una función hash para asignar claves a posiciones de índice de matriz para operaciones rápidas de inserción, eliminación y búsqueda.

  3. Colección desordenada: los elementos en HashMap no tienen un orden fijo, es decir, el orden de almacenamiento y recorrido de los elementos es impredecible.

  4. Permitir almacenar clave nula y valor nulo: HashMap permite almacenar nulo como clave y valor.

  5. Inserción, eliminación y búsqueda eficientes: dado que HashMap se implementa en función de una tabla hash, la complejidad de tiempo promedio de las operaciones de inserción, eliminación y búsqueda es O(1). Esto hace que HashMap funcione bien en escenarios de inserción, eliminación y búsqueda de grandes cantidades de datos.

  6. No seguro para subprocesos: HashMap no es seguro para subprocesos. Si se requiere acceso simultáneo a HashMap en un entorno de subprocesos múltiples, se requiere un control de sincronización externo.

Según las características anteriores, HashMap es adecuado para los siguientes escenarios:

  1. Almacenamiento y recuperación de pares clave-valor: dado que HashMap proporciona capacidades rápidas de almacenamiento y recuperación de pares clave-valor, a menudo se usa en escenarios donde el valor correspondiente debe obtenerse rápidamente de acuerdo con la clave.

  2. Almacenamiento de deduplicación: dado que la clave de HashMap es única, HashMap se puede utilizar para el almacenamiento de deduplicación. Almacene los elementos que se desduplicarán como claves en HashMap, y el valor puede estar vacío o ser un objeto de marcador de posición.

  3. Implementación de caché: debido a las características de recuperación y almacenamiento rápido de HashMap, se puede utilizar para implementar caché. Almacene la clave en caché como la clave de HashMap y almacene el valor en caché como el valor de HashMap.

  4. Almacenamiento sin un orden fijo: si no necesita mantener un orden específico de elementos, sino que solo se preocupa por el almacenamiento y la recuperación de pares clave-valor, HashMap es una opción adecuada.

        Cabe señalar que debido a la naturaleza desordenada de HashMap, si necesita almacenar elementos de manera ordenada, puede considerar usar LinkedHashMap, que mantiene el orden de inserción de los elementos en función de HashMap. Además, en un entorno de subprocesos múltiples, si necesita acceder a HashMap al mismo tiempo, puede considerar usar ConcurrentHashMap seguro para subprocesos.

2. Mapa de árbol

TreeMap es una clase de implementación de la interfaz Map en el marco de la colección Java y tiene las siguientes características:

  1. Almacenamiento ordenado: los pares clave-valor en TreeMap están ordenados y clasifica las claves según su orden natural o un comparador personalizado. Por defecto, el TreeMap se ordena según el orden natural de las claves, o según el comparador pasado.

  2. Basado en el árbol rojo-negro: la implementación subyacente de TreeMap se basa en la estructura de datos del árbol rojo-negro (árbol rojo-negro). Un árbol rojo-negro es un árbol de búsqueda binario autoequilibrado que mantiene el orden de los elementos y proporciona operaciones eficientes de inserción, eliminación y búsqueda.

  3. No se permite que las claves sean nulas: TreeMap no permite que las claves sean nulas porque necesita ordenarlas.

  4. Inserción, eliminación y búsqueda eficientes: dado que la capa inferior de TreeMap es un árbol rojo-negro, la complejidad temporal de las operaciones de inserción, eliminación y búsqueda es O (log n). Esto hace que TreeMap funcione bien en escenarios ordenados de almacenamiento y recuperación.

  5. No seguro para subprocesos: TreeMap no es seguro para subprocesos. Si necesita acceder a TreeMap simultáneamente en un entorno de subprocesos múltiples, debe realizar un control de sincronización externo.

Según las características anteriores, TreeMap es adecuado para los siguientes escenarios:

  1. Almacenamiento y recuperación ordenados: dado que los elementos en TreeMap están ordenados, a menudo se usa en escenarios que requieren almacenamiento y recuperación en el orden de las claves. Las claves se pueden ordenar según su orden natural o un comparador personalizado.

  2. Búsqueda de rango: dado que los elementos en TreeMap están ordenados, la búsqueda de rango se puede realizar fácilmente. El subMap dentro del rango especificado se puede obtener a través del método subMap() de TreeMap.

  3. Almacene los pares clave-valor que deben ordenarse: si necesita almacenar un conjunto de pares clave-valor y ordenarlos según el orden de las claves, TreeMap es una opción adecuada.

        Cabe señalar que, dado que TreeMap se implementa en función de un árbol rojo-negro, tiene un alto rendimiento para las operaciones de inserción, eliminación y búsqueda. Pero en comparación con HashMap, tiene una mayor huella de memoria porque cada elemento requiere espacio de almacenamiento adicional para mantener la estructura de árbol. Además, la clasificación de los elementos puede agregar cierta cantidad de tiempo de sobrecarga, especialmente en el caso de intercalaciones personalizadas. Por lo tanto, en escenarios con requisitos de alto rendimiento, es necesario evaluar cuidadosamente si elegir TreeMap.

3. Mapa hash vinculado

LinkedHashMap es una clase de implementación de la interfaz Map en el marco de la colección Java. Hereda de HashMap y además mantiene el orden de inserción de los elementos. Las siguientes son las características y escenarios aplicables de LinkedHashMap:

  1. Mantener el orden de inserción: LinkedHashMap utiliza internamente una lista doblemente enlazada para mantener el orden de inserción de los elementos. Por lo tanto, al atravesar LinkedHashMap, el orden de los elementos es coherente con el orden de inserción.

  2. Basado en una tabla hash: la implementación subyacente de LinkedHashMap todavía se basa en una tabla hash (HashMap). Además de usar una tabla hash para almacenar elementos, también se usa una lista enlazada para mantener el orden de inserción de los elementos.

  3. Permite almacenar clave nula y valor nulo: Al igual que HashMap, LinkedHashMap permite almacenar nulo como clave y valor.

  4. Colección ordenada: Dado que LinkedHashMap mantiene el orden de inserción de los elementos, se ordena. El orden de recorrido de los elementos es coherente con el orden de inserción.

  5. El rendimiento es similar al de HashMap: el rendimiento de la operación de inserción, eliminación y búsqueda de LinkedHashMap es similar al de HashMap, y la complejidad de tiempo promedio es O (1). Sin embargo, debido al mantenimiento de la estructura de la lista vinculada, LinkedHashMap tiene una huella de memoria ligeramente mayor que HashMap.

Según las características anteriores, LinkedHashMap es adecuado para los siguientes escenarios:

  1. Mantener el orden de inserción de elementos: LinkedHashMap es una opción adecuada si necesita almacenar y recorrer elementos en el orden en que se insertan.

  2. Orden de acceso de registro: además del orden de inserción, LinkedHashMap también se puede almacenar en orden de acceso. Al establecer el parámetro accessOrder en el constructor en verdadero, el elemento al que se accedió más recientemente se puede colocar al final de la lista vinculada. Esto se puede usar para implementar un caché basado en la estrategia LRU (Usado menos recientemente).

  3. Almacenamiento y recuperación ordenados: Dado que LinkedHashMap mantiene el orden de inserción, se puede utilizar en escenarios que requieren almacenamiento y recuperación ordenados de elementos. Los elementos se pueden obtener en orden de inserción o de acceso atravesando LinkedHashMap.

        Cabe señalar que LinkedHashMap tiene una huella de memoria ligeramente mayor que HashMap debido a la necesidad de mantener la estructura de la lista vinculada. En escenarios con altos requisitos de uso de memoria, debe elegir con cuidado. Además, en un entorno de subprocesos múltiples, si necesita acceder a LinkedHashMap al mismo tiempo, puede considerar usar ConcurrentLinkedHashMap seguro para subprocesos.

D cola

1. ArrayDeque

ArrayDeque es una clase de implementación de la interfaz Deque en el marco de la colección Java, que tiene las siguientes características:

  1. Cola de doble extremo: ArrayDeque es una cola de doble extremo que puede insertar y eliminar elementos en ambos extremos de la cola. Esto significa que los elementos se pueden insertar y quitar de la cabeza de la cola, y los elementos se pueden insertar y quitar de la cola de la cola.

  2. Matriz dinámica: la capa inferior de ArrayDeque se implementa con una matriz circular, que puede ajustar dinámicamente el tamaño de la matriz según sea necesario. Esto hace que ArrayDeque sea más eficiente en las operaciones de inserción y eliminación.

  3. No se permite almacenar elementos nulos: ArrayDeque no permite almacenar elementos nulos. Si intenta almacenar elementos nulos, se lanzará una NullPointerException.

  4. Operaciones eficientes: dado que ArrayDeque se implementa en base a matrices dinámicas, proporciona operaciones de inserción y eliminación eficientes. La complejidad de tiempo promedio de las operaciones de inserción y eliminación en ambos extremos de la cola es O(1).

  5. No seguro para subprocesos: ArrayDeque no es seguro para subprocesos. Si es necesario acceder a ArrayDeque simultáneamente en un entorno de subprocesos múltiples, se requiere un control de sincronización externo.

Según las características anteriores, ArrayDeque es adecuado para los siguientes escenarios:

  1. Operación eficiente de cola de dos extremos: dado que ArrayDeque admite operaciones de inserción y eliminación al principio y al final de la cola, es muy adecuado para usar como una cola de dos extremos. Se puede utilizar en escenarios que requieren operaciones frecuentes al principio y al final de la cola al mismo tiempo.

  2. Operación de pila eficiente: dado que ArrayDeque tiene las características de una cola de dos extremos, también se puede usar como una pila. Los elementos se pueden insertar al final de la cola a través del método push() y los elementos se pueden eliminar del final de la cola a través del método pop() para lograr operaciones de pila eficientes.

  3. Búfer temporal: debido a la implementación de matriz dinámica de ArrayDeque, se puede utilizar como un búfer temporal. Los datos que deben almacenarse temporalmente pueden colocarse en ArrayDeque y procesarse en orden de inserción sin un búfer de tamaño fijo.

        Cabe señalar que ArrayDeque no es seguro para subprocesos. Si es necesario acceder a ArrayDeque al mismo tiempo en un entorno de subprocesos múltiples, se requiere un control de sincronización externo. Además, en comparación con LinkedList, ArrayDeque tiene un mejor rendimiento en las operaciones de inserción y eliminación, pero un rendimiento deficiente en los elementos de acceso aleatorio. Por lo tanto, ArrayDeque se puede seleccionar en escenarios donde se requieren operaciones frecuentes de inserción y eliminación sin acceso aleatorio a los elementos.

2. Cola de prioridad

PriorityQueue es una clase de implementación de la interfaz Queue en el marco de colección de Java, que tiene las siguientes características:

  1. Priority Queue: PriorityQueue es una cola especial que ordena los elementos según su prioridad. En PriorityQueue, los elementos se clasifican en orden natural o mediante un comparador personalizado.

  2. Basado en montón: la implementación subyacente de PriorityQueue se basa en la estructura de datos del montón (Heap). Un montón es un árbol binario completo, que puede garantizar que el valor de cada nodo sea mayor (o menor) que el valor de sus nodos secundarios, para lograr el orden de los elementos.

  3. Operaciones rápidas de inserción y eliminación: dado que PriorityQueue se implementa en función de un montón, la complejidad de tiempo promedio de las operaciones de inserción y eliminación es O (log n). Esto hace que PriorityQueue tenga un alto rendimiento en escenarios donde las operaciones de inserción y eliminación deben realizarse de acuerdo con la prioridad.

  4. No se permite el almacenamiento de elementos nulos: PriorityQueue no permite el almacenamiento de elementos nulos. Si intenta almacenar elementos nulos, se lanzará una NullPointerException.

  5. No seguro para subprocesos: PriorityQueue no es seguro para subprocesos. Si necesita acceder a PriorityQueue al mismo tiempo en un entorno de subprocesos múltiples, debe realizar un control de sincronización externo.

Según las características anteriores, PriorityQueue es adecuado para los siguientes escenarios:

  1. Procesamiento de prioridad: dado que PriorityQueue se ordena según la prioridad de los elementos, es muy adecuado para escenarios que deben procesarse según la prioridad. Los elementos con diferentes prioridades pueden colocarse en PriorityQueue y procesarse según el orden de prioridad.

  2. Clasificación de montones: dado que la implementación subyacente de PriorityQueue se basa en el montón, se puede usar para implementar el algoritmo de clasificación de montones. Heap sorting es un algoritmo de clasificación eficiente. Al insertar los elementos que se van a clasificar en PriorityQueue en secuencia y luego sacarlos en orden de prioridad, puede obtener resultados ordenados.

  3. Programación de tareas: PriorityQueue se puede utilizar para implementar colas de programación de tareas. Las tareas que deben ejecutarse pueden colocarse en PriorityQueue y programarse de acuerdo con la prioridad de las tareas.

        Cabe señalar que PriorityQueue no es seguro para subprocesos. Si necesita acceder a PriorityQueue simultáneamente en un entorno de subprocesos múltiples, debe realizar un control de sincronización externo. Además, debido a que PriorityQueue se implementa en función de un montón, tiene un buen rendimiento en la clasificación e inserción de datos a gran escala, pero tiene un rendimiento deficiente en los elementos de acceso aleatorio. Por lo tanto, se requiere evaluación y selección en escenarios con altos requisitos para elementos de acceso aleatorio.

Bienvenido a visitar: http://mumuxi.chat/

 

Supongo que te gusta

Origin blog.csdn.net/zz18532164242/article/details/130966701
Recomendado
Clasificación