Colección de Java

Iterador de colección

Actualmente hay tres iteradores en Java: Iterator Iterable ListIterator.

  1. Primero mire la interfaz del iterador:

public interface Iterator { boolean hasNext (); E next (); void remove (); } El significado de la interfaz API proporcionada es el siguiente: hasNext (): determina si hay otro objeto en la colección. next (): Devuelve el siguiente objeto de la colección y mueve el puntero de acceso un bit. remove (): Elimina el objeto devuelto llamando al método next () de la colección. En la primera versión del JDK, solo había una forma de atravesar la colección, y era operar a través del Iterador. Los ejemplos específicos son los siguientes:








复制 代码
Lista lista = nueva ArrayList <> ();
list.add (10);
list.add (20);
list.add (30);
Iterador iter = list.iterator ();
while (iter.hasNext ()) { Integer next = iter.next (); System.out.println (siguiente); if (siguiente == 20) { iter.remove (); } } 复制 代码2. Iterable 接口







1
2
3
4
5
6
7
8
9
10
11
12
13
14
interfaz pública Iterable { Iterator iterator (); // desde JDK 1.8 default void forEach (Consumer <? Super T> action) { Objects.requireNonNull (action); for ( T t: this) { action.accept (t); } } // desde JDK 1.8 Spliterator spliterator () predeterminado { return Spliterators.spliteratorUnknownSize (iterator (), 0); } } El  método Iterator () se proporciona en la interfaz Iterable Devuelve un iterador, por lo que una colección que implementa la interfaz Iterable aún puede usar iteradores para atravesar y manipular objetos en la colección. En JDK 1.8, se agregó un nuevo método forEach () a la interfaz Iterable, que permite un bucle for mejorado para atravesar objetos.













为什么要设计两个接口Iterable和Iterator?Iterator接口的保留可以让子类去实现自己的迭代器,而Iterable接口更加关注于for-each的增强语法。
  1. ListIterator

ListIterator hereda la interfaz Iterator y solo existe en la colección List. Puede devolver el iterador cuyo índice inicial es index llamando al método. Hay varios métodos importantes en ListIterator, la mayoría de los cuales tienen el mismo significado que el definido en Iterator. Además, de acuerdo con el iterador devuelto, se puede lograr un recorrido bidireccional.

1
2
3
4
5
6
7
8
9
10
11
12
public interface ListIterator extiende Iterator { boolean hasNext (); E next (); boolean hasPrevious (); E previous (); int nextIndex (); int previousIndex (); void remove (); // Reemplazar el elemento del subíndice actual, es decir, el último elemento visitado void set (E e); void add (E e); ) Three, Map and Collection interface











La interfaz Map y la interfaz Collection son dos escuelas importantes en el marco de la colección de Java. Collection almacena los elementos de la colección en sí, y Map almacena pares clave-valor <clave, valor>, pero algunas subclases de Collection utilizan Map para lograrlo. Por ejemplo: la capa inferior de HashSet usa HashMap, la capa inferior de TreeSet usa TreeMap y la capa inferior de LinkedHashSet usa LinkedHashMap.

La estructura de datos de la interfaz del mapa tiene la forma de <clave, valor>. La clave asigna el valor. Una clave corresponde a un valor. La clave no se puede repetir y el valor se puede repetir. La interfaz del mapa se subdivide en diferentes categorías:

SortedMap接口:该类映射可以对<key, value>按照自己的规则进行排序,具体实现有 TreeMap
AbsractMap抽象类:它为子类提供好一些通用的API实现,所有的具体Map如HashMap都会继承它

La interfaz de Colección proporciona métodos comunes para todas las colecciones (tenga en cuenta que Map no se incluye aquí):
agregar método: agregar (E e) / addAll (Colección <? Extiende E> var1) / addAll (int índice, Colección <? Extiende E> var1)
Método de búsqueda: contiene (Objeto var1) / contieneAll (Colección <?> Var1) /
Consulta la información de la colección en sí: tamaño () / isEmpty ()
Método de eliminación: remove (O o) / removeAll (Colección <?> Var1) / Encuentra la intersección : RetainAll (Colección c)

... ...

La interfaz Colección subdivide las colecciones en diferentes categorías:

Set接口:一个不允许存储重复元素的无序集合,具体实现有HashSet / TreeSet···
List接口:一个可存储重复元素的有序集合,具体实现有ArrayList / LinkedList···
Queue接口:一个可存储重复元素的队列,具体实现有PriorityQueue / ArrayDeque···
  1. Explicación detallada de la interfaz Map El
    sistema Map se divide principalmente en dos tipos de colecciones: AbstractMap y SortedMap.
    AbstractMap es una extensión de la interfaz Map. Define los métodos comunes de las colecciones Map ordinarias, que pueden evitar que las subclases escriban una gran cantidad del mismo código. Las subclases se pueden repetir después de heredar AbstractMap. Escriba su método e implemente lógica adicional para proporcionar más funciones externas.
    La interfaz SortedMap define el comportamiento de clasificación de Map. Cuando las subclases lo implementan, todos los métodos deben reescribirse para proporcionar funciones de clasificación al mundo exterior.

1.1 HashMap
HashMap es una colección del uso más común de tablas hash para almacenar elementos. Cuando se agrega un elemento al HashMap, el valor hash de la clave se convertirá en el subíndice de índice de la matriz para determinar la ubicación de almacenamiento. Al buscar el elemento, se basa en el hash de la clave. La dirección se convierte en el subíndice de índice de la matriz para determinar la posición de búsqueda.
La capa inferior de HashMap se implementa con tres estructuras de datos: matriz + lista enlazada + árbol rojo-negro, que es una colección no segura para subprocesos.

Cuando la adición de elementos tiene un conflicto de hash, HashMap vinculará los elementos con la misma dirección en una lista vinculada. Si la longitud de la lista vinculada es mayor que 8 y la longitud de la matriz es mayor que 64, se convertirá en una estructura de datos de árbol rojo-negro.

Un breve resumen sobre HashMap:
1. Es el tipo de colección de mapas más utilizado en la colección. La capa inferior se compone de matriz + lista vinculada + árbol rojo-negro;
2. HashMap no es seguro para subprocesos;
3. Al insertar un elemento, calcule el valor hash del elemento , Se convierte en un subíndice de matriz mediante la función de mapeo hash; cuando se busca un elemento, la posición del elemento de posicionamiento del subíndice de matriz se obtiene mediante la función de mapeo hash.

1.2 LinkedHashMap
LinkedHashMap se puede considerar como una combinación de HashMap y LinkedList: agrega una lista doblemente enlazada sobre la base de HashMap y almacena el orden de inserción de cada elemento por defecto, pero debido a esta lista doblemente enlazada, LinkedHashMap puede implementar la estrategia de eliminación de caché LRU. Porque podemos configurar esta lista doblemente enlazada para que se ordene según el orden de acceso de los elementos

1
2
3
4
// El nodo principal
transitorio LinkedHashMap.Entry <K, V> head;
// El nodo
final transitorio LinkedHashMap.Entry <K, V> tail;
LinkedHashMap se puede usar para implementar la estrategia de eliminación de caché LRU, porque proporciona un método :

1
2
3
protected boolean removeEldestEntry (java.util.Map.Entry <K, V> eldest) { return false; } Este método puede eliminar el nodo más cercano al encabezado de la lista vinculada, y el código fuente del método get (clave) es el siguiente , Su función es mover la posición del nodo:


1
2
3
4
5
6
7
8
public V get (Object key) { Node <K, V> e; if ((e = getNode (hash (key), key)) == null) return null; if (accessOrder) afterNodeAccess (e); return e.value; } Siempre que se llame a get (key) y accessOrder = true, el nodo se actualizará al final de la lista vinculada. La lógica específica está en afterNodeAccess (). El código fuente es el siguiente:







Copiar el código
void afterNodeAccess (Node <K, V> e) {// mover el nodo al último
  LinkedHashMap.Entry <K, V> last;
  if (accessOrder && (last = tail)! = E) {     LinkedHashMap.Entry <K, V> p = (LinkedHashMap.Entry <K, V>) e, b = p. Antes, a = p.after;     p.after = null;     if (b == null) head = a;      else b.after = a;     if (a! = null) a.before = b;     else last = b;     if (last == null) head = p;     else {       p.before = last;       last.after = p;     }     tail = p;     ++ modCount;   } } Copiar código Especifique accessOrder = true, puede configurar la lista vinculada para que se organice en el orden de acceso, y accessOrder se puede configurar a través del constructor proporcionado.
















public LinkedHashMap (int initialCapacity, float loadFactor, boolean accessOrder) { super (initialCapacity, loadFactor); this.accessOrder = accessOrder; } Reescribe el método removeEldestEntry (), lógica definida internamente, generalmente para determinar si la capacidad alcanza el límite superior y, de ser así, realizar la eliminación .



Resuma dos puntos sobre LinkedHashMap:
1. La capa inferior mantiene una lista doblemente vinculada, heredando HashMap, por lo que no es seguro para subprocesos
2. LinkedHashMap puede implementar la estrategia de eliminación de caché LRU, el principio es definir elementos eliminados estableciendo accessOrder en verdadero y reescribiendo el método removeEldestEntry Las condiciones a cumplir en ese momento.

1.3 TreeMap
TreeMap es una subclase de SortedMap, por lo que tiene una función de clasificación. Se implementa en función de los datos del árbol rojo-negro. Cada par clave-valor <clave, valor> es un nodo, que está naturalmente ordenado por clave por defecto. Una es que se puede ordenar por reglas personalizadas pasando un Comparador personalizado.

// De acuerdo con la clasificación natural de la clave, la clasificación natural de Integer es ascendente
TreeMap <Integer, Object> naturalSort = new TreeMap <> ();
// Clasificación personalizada, ordenando en orden descendente de la clave
TreeMap <Integer, Object> customSort = new TreeMap <> ( (o1, o2) -> Integer.compare (o2, o1));

Cada nodo del árbol rojo-negro en la figura es una entrada. La clave y el valor no están marcados aquí. Estos elementos se han clasificado de acuerdo con la clave, ¡y toda la estructura de datos está en un estado ordenado!
Con respecto a la clasificación natural y la clasificación personalizada: clasificación
natural: la clave debe implementar la interfaz Comparable.
Dado que la clase Integer implementa la interfaz Comparable, de acuerdo con la regla de ordenación natural, la clave se ordena de pequeña a grande.

TreeMap <Integer, String> treeMap = new TreeMap <> ();
treeMap.put (2, "贰");
treeMap.put (1, "壹");
System.out.print (treeMap);
// {1 = 一, 2 = 2}
Clasificación personalizada: al inicializar TreeMap, pase un nuevo Comparador y no se requiere la clave para implementar la interfaz Comparable

Copie el código
TreeMap <Integer, String> treeMap = new TreeMap <> ((o1, o2) -> Integer.compare (o2, o1));
treeMap.put (1, "壹");
treeMap.put (2, "贰 ");
treeMap.put (4,"
"); treeMap.put (3," 三 ");
System.out.println (treeMap);
// {4 = 4, 3 = , 2 = 2, 1 = 一}
Copiar código
Se introducen principalmente tres puntos sobre TreeMap:
1. Su capa inferior está implementada por árboles rojo-negros, y la complejidad del tiempo de operación es O (logN);
2. TreeMap puede ordenar las claves de forma natural o personalizada , Comparator debe pasarse para una clasificación personalizada, mientras que la clasificación natural requiere claves para implementar la interfaz Comparable;
3. TreeMap no es seguro para subprocesos.

1.4 WeakHashMap
La estructura de datos de los elementos almacenados en la parte inferior de WeakHashMap es una matriz + una lista vinculada, y no hay un árbol rojo-negro. Rara vez se usa en el desarrollo diario. Se implementa en base a Map. La clave en Entry se borrará en cada recolección de basura. Es adecuada para elementos a los que se accede brevemente o una vez, se almacenan en caché en WeakHashMap y se reciclan lo antes posible.

public class WeakHashMap <K, V> extiende AbstractMap <K, V> implementa Map <K, V> { }   Cuando Entry es GC, ¿cómo percibe WeakHashMap que un elemento es reciclado?

    在 WeakHashMap 内部维护了一个引用队列queue:

Private final ReferenceQueue queue = new ReferenceQueue <> (); La
cola contiene todas las claves descartadas por GC. Cuando la JVM enciende el GC, si la clave en WeakHashMap se recicla, la clave se colocará en la cola, en expungeStaleEntries () Atraviesa la cola, saca todas las claves de la cola y bórralas en WeakHashMap para lograr la sincronización.

El elemento marcado con la línea de puntos en la figura se eliminará la próxima vez que se acceda a WeakHashMap. WeakHashMap realizará una serie de ajustes internamente, por lo que la función de la cola es marcar los elementos que se han eliminado por GC.
Hay tres puntos a tener en cuenta sobre WeakHashMap:
1. Su clave es una especie de clave débil. Cuando se coloca en WeakHashMap, se reciclará en cualquier momento, por lo que no hay garantía de que existan ciertos elementos de acceso;
2. Se basa en Map ordinario para su implementación. Una colección no segura para subprocesos;
3. WeakHashMap se usa generalmente como un caché, adecuado para almacenar pares clave-valor a los que solo se debe acceder una vez o que solo deben almacenarse durante un corto tiempo.

1.5 HashTable La
estructura de almacenamiento subyacente de Hashtable es una matriz + lista vinculada, que es una colección segura para subprocesos. Cuando la lista enlazada es demasiado larga, la eficiencia de la consulta es demasiado baja y la Hashtable quedará bloqueada durante mucho tiempo, por lo que en un entorno concurrente el rendimiento es muy pobre, básicamente se elimina y rara vez se usa. Seguridad de subprocesos, a todos sus métodos se les ha agregado la palabra clave sincronizada. La longitud predeterminada de HashTable es 11 y el factor de carga es 0,75 F, es decir, cuando el número de elementos alcanza el 75% de la longitud del arreglo, se realizará una expansión y cada expansión será el doble de la longitud original del arreglo.

  1. Explicación detallada del
    sistema de recopilación de colecciones La interfaz de nivel superior del sistema de recopilación de colecciones es Colección, que especifica una serie de métodos bajo la colección.
    La colección se puede dividir en tres tipos de colecciones:
    interfaces de lista, conjunto y conjunto de cola : los elementos duplicados no se pueden almacenar y cualquier operación debe asignarse a los elementos de posicionamiento interno de la colección a través de una función hash, y los elementos internos de la colección están desordenados por defecto.
    Interfaz de lista: puede almacenar elementos repetidos, y los elementos de la colección están ordenados según el orden en que se insertan los elementos, y se puede acceder a los elementos por índice.
    Interfaz de la cola: La cola se utiliza como estructura de almacenamiento y los elementos de la colección están ordenados, solo se pueden operar los elementos del nodo principal y no se puede acceder a los elementos en el medio de la cola.
    Las tres interfaces anteriores son las implementaciones más comunes y abstractas, y dentro de cada interfaz de colección, habrá un rendimiento más específico, derivando una variedad de funciones adicionales, de modo que los desarrolladores puedan comparar las ventajas de cada colección y usarlas en función de la mejor.

2.1 Interfaz del conjunto La interfaz del
conjunto hereda la interfaz de la colección y es una colección que no incluye elementos repetidos. Para ser más precisos, dos elementos cualesquiera en el conjunto no aparecerán o1.equals (o2), y el conjunto solo puede almacenar como máximo un elemento de valor NULO. .

En el sistema de recopilación de conjuntos, debemos centrarnos en dos puntos: al
almacenar elementos variables, debemos tener mucho cuidado, porque cada vez que cambia el estado del elemento, es imposible que aparezcan dos elementos iguales en el conjunto, a saber, o1.equals ( o2) = verdadero, por lo que generalmente no cambie los elementos almacenados en el Conjunto, de lo contrario, la función de equals () se destruirá.
El papel más importante de Set es juzgar pesado, ¡y el papel más importante en el proyecto es juzgar pesado!

La
capa inferior de HashSet HashSet se implementa con HashMap, podemos observar sus múltiples métodos de construcción, que son esencialmente nuevos y un HashMap

Copie el código
public class HashSet the Set the amplía AbstractSet the implements, the Cloneable, the Serializable { public HashSet () { this.map new new = the HashMap (); } public HashSet (int initialCapacity, a float loadFactor) { this.map new new = the HashMap (initialCapacity, loadFactor) ; } public HashSet (int initialCapacity) { this.map = new HashMap (initialCapacity); } } Copiar código Podemos observar cómo el método add () y el método remove () injertan la operación de HashSet en HashMap.











Copie el código
Privado el PRESENTE Objeto final estático = new new Object ();
public Boolean el Agregar (E E) { return this.map.put (E, the PRESENT) == null; } public Boolean Remove (Object O) { return this.map. remove (o) == PRESENT; } Copia el valor del código HashMap. Los desarrolladores que usan HashSet solo deben prestar atención a la clave que se debe insertar, protegiendo el valor de HashMap






HashSet se implementa sobre la base de HashMap, por lo que muchos lugares se pueden vincular a HashMap:
Estructura de datos subyacente: HashSet también usa matriz + lista vinculada + árbol rojo-negro para lograr la
seguridad de los subprocesos: debido a la implementación de HashMap, HashMap en sí no es seguro para subprocesos y no está en HashSet Agregue una estrategia de sincronización adicional, por lo que HashSet también es inseguro para
almacenar el estado del objeto en HashSet, es mejor no cambiarlo, porque es posible que después de que se cambie el estado, dos elementos o1.equals (o2) aparezcan en el conjunto, destruyendo iguales ( ) Semántica.

LinkedHashSet
LinkedHashSet tiene un pequeño código lamentable, como sigue:

复制 代码
la clase pública LinkedHashSet
extiende HashSet
implementa Set, Cloneable, java.io.Serializable {

private static final long serialVersionUID = -2851667679971038690L;
public LinkedHashSet(int initialCapacity, float loadFactor) {
    super(initialCapacity, loadFactor, true);
}
public LinkedHashSet(int initialCapacity) {
    super(initialCapacity, .75f, true);
}
public LinkedHashSet() {
    super(16, .75f, true);
}
public LinkedHashSet(Collection<? extends E> c) {
    super(Math.max(2*c.size(), 11), .75f, true);
    addAll(c);
}
@Override
public Spliterator<E> spliterator() {
    return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
}

}
Evaluación de Amazon www.yisuping.com

Supongo que te gusta

Origin blog.csdn.net/weixin_45032957/article/details/108576533
Recomendado
Clasificación