[Serie de código fuente de contenedor Java] Análisis de código fuente TreeSet

La estructura general de TreeSet es similar a HashSet. Para obtener más detalles, puede ver el análisis del código fuente de HashSet en el artículo anterior. Aquí, la capa inferior es TreeMap, por lo que hereda la función de clasificación de claves de TreeMap. Al iterar, también puede iterar según el orden de clasificación de las claves. Y este artículo analizará principalmente las dos ideas de reutilización que se utilizan cuando TreeSet reutiliza TreeMap:

  • TreeSet usa directamente algunas funciones de TreeMap y se envuelve en una nueva API
  • TreeSet define la API que desea, define la especificación de la interfaz usted mismo y permite que TreeMap la implemente

1 Reutilizar TreeMap idea uno

1.1 Resumen

TreeSet usa directamente algunas funciones de TreeMap y se envuelve en una nueva API

1.2 Razón

Básicamente, estos métodos de adición son relativamente simples de implementar sin una lógica complicada, por lo que TreeSet es relativamente simple de implementar por sí mismo;

1.3 Ejemplo: add ()

Por ejemplo, el método add de TreeSet usa esta idea:

public boolean add(E e) {
    
    
        return m.put(e, PRESENT)==null;
}

Como puede ver, la capa inferior usa directamente el método put de TreeMap, solo úselo directamente.

2 Reutilizar la idea dos de TreeMap

2.1 Resumen

TreeSet define la API que desea, define la especificación de la interfaz usted mismo y permite que TreeMap la implemente

2.2 Razón

Esta idea es adecuada principalmente para escenas complejas, como escenas iterativas. Las escenas de TreeSet son complejas. Por ejemplo, necesita poder iterar desde cero, por ejemplo, para poder tomar el primer valor, por ejemplo, para poder tomar el último valor, además de que la estructura subyacente de TreeMap es más complicada, TreeSet Puede que no esté claro acerca de la compleja lógica subyacente a TreeMap.

En este momento, deje que TreeSet implemente una lógica de escena tan compleja, y TreeSet no podrá manejarla. Es mejor dejar que TreeSet defina la interfaz y dejar que TreeMap sea responsable de la implementación. TreeMap es muy claro acerca de la estructura compleja subyacente y es preciso y simple de implementar.

2.3 Ejemplo: iterador ()

Necesita iterar los elementos en el TreeSet, también debería ser como agregar, usar directamente la capacidad iterativa existente de HashMap, por ejemplo, como el siguiente:

// 模仿思路一的方式实现
public Iterator<E> descendingIterator() {
    
    
    // 直接使用 HashMap.keySet 的迭代能力
    return m.keySet().iterator();
}

Esta es la realización de la idea uno. TreeSet combina TreeMap y selecciona directamente las capacidades subyacentes de TreeMap para el empaquetado, pero la implementación real de TreeSet es completamente opuesta. Veamos el código fuente:

// NavigableSet 接口,定义了迭代的一些规范,和一些取值的特殊方法
// TreeSet 实现了该方法,也就是说 TreeSet 本身已经定义了迭代的规范
public interface NavigableSet<E> extends SortedSet<E> {
    
    
    Iterator<E> iterator();
    E lower(E e);
}  
// m.navigableKeySet() 是 TreeMap 写了一个子类实现了 NavigableSet接口,实现了 TreeSet 定义的迭代规范
public Iterator<E> iterator() {
    
    
    return m.navigableKeySet().iterator();
}

La captura de pantalla del código fuente de implementación de la interfaz NavigableSet en TreeMap es la siguiente:
Inserte la descripción de la imagen aquí
De la captura de pantalla (la captura de pantalla está en TreeMap), podemos ver que TreeMap implementa varios métodos especiales definidos por TreeSet. Podemos ver que esta idea es que TreeSet define la especificación de la interfaz y TreeMap se encarga de la implementación, la idea de realización y la idea son opuestas.

para resumir

La relación de llamada entre los esquemas 1 y 2 es que TreeSet llama a TreeMap, pero la relación de realización de funciones es completamente opuesta

  • La primera es que la definición e implementación de funciones están en TreeMap, y TreeSet es solo una simple llamada.
  • Después de que el segundo TreeSet defina la interfaz, deje que TreeMap implemente la lógica interna. TreeSet es responsable de la definición de la interfaz y TreeMap es responsable de la implementación específica. En este caso, debido a que la interfaz está definida por TreeSet, la implementación debe ser lo que más desea TreeSet. TreeSet incluso ambos Sin embalaje, puede escupir el valor de devolución directamente.

Por último, hablar sobre la estructura interna y los principios de los conjuntos TreeSet y HashSet.

  • La capa inferior de HashSet encapsula las capacidades de HashMap. Por ejemplo, el método add usa el método put de HashMap directamente, que es relativamente simple
  • TreeSet encapsula y reutiliza principalmente las capacidades subyacentes de TreeMap, utilizando dos ideas de reutilización de TreeSet

Supongo que te gusta

Origin blog.csdn.net/weixin_43935927/article/details/108525572
Recomendado
Clasificación