7. Analyse du code source de TreeMap

1. Structure de données
La structure de données sous-jacente de TreeMap est un arbre rouge-noir, qui est identique à l'arborescence rouge-noir de HashMap. La différence est que TreeMap tire parti de l'arbre rouge-noir avec de petits nœuds à gauche et de grands nœuds à droite, en triant en fonction de la clé, de sorte que chaque élément puisse être inséré dans la position appropriée de l'arbre rouge-noir, en maintenant la relation de taille de la clé, et convient au tri des clés. Scène. Étant donné que la couche inférieure utilise une structure arborescente rouge-noire équilibrée, la complexité temporelle des méthodes telles que containsKey, get, put et remove sont toutes log (n).
Code source

public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable{
    
    
	//比较器,如果外部有传进来Comparator比较器,首先用外部的
	//如果外部比较器为空,则使用key实现的Comparable的compareTo方法
	private final Comparator<? super K> comparator;
	 
	//红黑树的根节点
	private transient Entry<K,V> root;
	 
	//红黑树中已有的元素大小
	private transient int size = 0;
	 
	//树结构变化的版本号,用于迭代过程中的快速失败场景
	private transient int modCount = 0;
	 
	//红黑树的节点
	static final class Entry<K,V> implements Map.Entry<K,V> {
    
    }
}

2. Nouvellement
ajouté Le code source de la clé et de la valeur nouvellement ajoutées est indiqué ci-dessous.

public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>, Cloneable, java.io.Serializable{
    
    
	public V put(K key, V value) {
    
    
		Entry<K,V> t = root;
		//判断红黑树的节点是否为空,为空的话,新增的节点直接作为根节点
		if (t == null) {
    
    
		  //compare方法限制了key不能为null
		  compare(key, key); 
		  //成为根节点
		  root = new Entry<>(key, value, null);
		  size = 1;
		  modCount++;
		  return null;
		}
		int cmp;
		Entry<K,V> parent;
		//根据红黑树左小右大的特性,进行判断,找到新增节点的父节点
		Comparator<? super K> cpr = comparator;
		if (cpr != null) {
    
    
		  //自旋找到key应该新增的位置
		  do {
    
    
		      //一次循环结束时,parent就是上次比过的对象
		      parent = t;
		      //通过compare来比较key的大小
		      cmp = cpr.compare(key, t.key);
		      //key小于t,把t左边的值赋予t,因为红黑树左边的值比较小,循环再比
		      if (cmp < 0)
		          t = t.left;
		      //key大于t,把t右边的值赋予t,因为红黑树右边的值比较大,循环再比
		      else if (cmp > 0)
		          t = t.right;
		      //如果相等的话,直接覆盖原值
		      else
		          return t.setValue(value);
		      //t为空,说明已经到叶子节点了
		  } while (t != null);
		}else {
    
    
		  if (key == null)
		      throw new NullPointerException();
		  @SuppressWarnings("unchecked")
		  Comparable<? super K> k = (Comparable<? super K>) key;
		  do {
    
    
		      parent = t;
		      cmp = k.compareTo(t.key);
		      if (cmp < 0)
		          t = t.left;
		      else if (cmp > 0)
		          t = t.right;
		      else
		          return t.setValue(value);
		  } while (t != null);
		}
		//在父节点的左边或右边插入新增节点
		Entry<K,V> e = new Entry<>(key, value, parent);
        //cmp代表最后一次对比的大小,小于0 ,代表e在上一节点的左边
		if (cmp < 0)
		  parent.left = e;
		//大于0 ,代表e在上一节点的右边,相等的情况第二步已经处理了
		else
		  parent.right = e;
		//着色旋转,直至达到平衡
		fixAfterInsertion(e);
		size++;
		modCount++;
		return null;
	}
}

Analyse du code source
1. Lors de l'ajout d'un nouveau nœud, utilisez la caractéristique de l'arbre rouge-noir selon laquelle la gauche est petite et la droite est grande, et le nœud racine est continuellement recherché jusqu'à ce que la valeur du nœud soit nulle. Si le nœud est nul, cela signifie que le nœud feuille est atteint.
2. Pendant le processus de recherche, si la valeur de clé existe déjà, elle sera écrasée directement.
3. TreeMap ne prend pas en charge la clé nulle.

Je suppose que tu aimes

Origine blog.csdn.net/Jgx1214/article/details/109096646
conseillé
Classement