7.TreeMapソースコード分析

1.データ構造
TreeMapの基礎となるデータ構造は赤黒ツリーであり、HashMapの赤黒ツリー構造と同じです。違いは、TreeMapは、左ノードが小さく右ノードが大きい赤黒ツリーを利用してキーに従ってソートするため、各要素を赤黒ツリーの適切な位置に挿入して、キーのサイズ関係を維持し、キーのソートに適していることです。シーン。最下層はバランスの取れた赤黒ツリー構造を使用しているため、containsKey、get、put、removeなどのメソッドの時間の複雑さはすべてlog(n)です。
ソースコード

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.新しく
追加れたキーと値のソースコードを以下に示します。

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;
	}
}

ソースコード分析
1.新しいノードを追加するときは、左が小さく右が大きいという赤黒の木の特性を使用して、ノードの値がnullになるまでルートノードを継続的に検索します。ノードがnullの場合は、リーフノードに到達したことを意味します。
2.検索プロセス中に、キー値がすでに存在することが判明した場合、そのキー値は直接上書きされます。
3.TreeMapはnullキーをサポートしていません。

おすすめ

転載: blog.csdn.net/Jgx1214/article/details/109096646