1、TreeMap特点及其使用
TreeMap的底层实现是一颗红黑树,学过数据结构的我们都知道红黑树也是平衡二叉树的一种,其最大的特点在与有序,其父节点左边的所有节点的值都是小于父节点的值,父节点右边所有节点的值都是大于父节点的值。故中序遍历以后得到的序列肯定是一个有序序列。TreeMap基于此数据结构故也是有序的
2、TreeMap数据结构
2、1存储
TreeMap的存储以及TreeMap中节点的储存
//比较器
private final Comparator<? super K> comparator;
//红黑树的根节点
private transient Entry<K,V> root;
/**
* The number of entries in the tree
*/
//树中节点的个数
private transient int size = 0;
/**
* The number of structural modifications to the tree.
*/
private transient int modCount = 0;
//红黑树中节点的存储结构
static final class Entry<K,V> implements Map.Entry<K,V> {
//本身所存储的key-value值
K key;
V value;
//左孩子的引用
Entry<K,V> left;
//右孩子的引用
Entry<K,V> right;
//指向其父节点
Entry<K,V> parent;
//指定红黑树的颜色属性
boolean color = BLACK;
}
2、2构造方法
// 无参构造方法,使用默认构造器
public TreeMap() {
comparator = null;
}
// 自定义比较器的构造方法
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
//将给定的Map对象的构造尾TreeMap,使用默认的构造器
public TreeMap(Map<? extends K, ? extends V> m) {
comparator = null;
putAll(m);
}
//将SortedMap对象转换尾TreeMap
public TreeMap(SortedMap<K, ? extends V> m) {
// 使用已知对象的构造器
comparator = m.comparator();
try {
buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
} catch (java.io.IOException cannotHappen) {
} catch (ClassNotFoundException cannotHappen) {
}
}
3、核心方法
put方法向TreeMap中添加一个元素,在编程方法上类似于数据结构中的二叉排序树节点的插入 //put方法,向一颗TreeMap中添加指定元素
public V put(K key, V value) {
//获取根节点位置
Entry<K,V> t = root;
//如果TreeMap(根节点)为空
if (t == null) {
compare(key, key); // type (and possibly null) check
//申请根节点,key值,value值,父节点的值
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
//自定义比较器的情况
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
//当前值比父节点值小,进入其左子树遍历
if (cmp < 0)
t = t.left;
else if (cmp > 0)
//比父节点值大,进入右子树遍历
t = t.right;
else
//如果比较的关键字相同则进行值的覆盖
return t.setValue(value);
} 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);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
get方法,根据指定的key获取其value值
//根据key值获取指定的value
public V get(Object key) {
Entry<K,V> p = getEntry(key);
return (p==null ? null : p.value);
}
//get的核心方法
final Entry<K,V> getEntry(Object key) {
// Offload comparator-based version for sake of performance
if (comparator != null)
return getEntryUsingComparator(key);
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
//类似于数据结构中的二叉搜索树的查找
//从红黑树的根节点开始
Entry<K,V> p = root;
while (p != null) {
int cmp = k.compareTo(p.key);
if (cmp < 0)
//进入左子树
p = p.left;
else if (cmp > 0)
//进入右子树
p = p.right;
else
//查询成功
return p;
}
//查询失败
return null;
}
未完待续.............
附:以上皆为本人原创,转载请注明出处