TreeSet 类、TreeMap 类
概述
1、TreeSet 底层是 TreeMap,维护红黑树
2、相同
(1)有序集合,存储的值都有序,不传入 Comparator 的情况下,默认按键自然排序
(2)非同步集合,不能在多线程之间共享,可以使用方法 Collections.synchroinzedMap() 实现同步
(3)运行速度都要比 Hash 集合慢,内部对元素的操作时间复杂度为 O(logN),而 HashMap / HashSet 则为 O(1)
(4)不允许存储 null,因为它每次添加新元素时,都会比较值,然后进行排序,所以在内部发生的事情是,它将新添加的null值与现有值进行比较,因此它将抛出 NullPointerException
3、不同
(1)TreeSet、TreeMap 分别实现 Set、Map 接口
(2)TreeSet 只存储一个 key,而 TreeMap 存储 key-value(仅 key 对象有序)
(3)TreeSet 中不能有重复对象,而 TreeMap 中 key 不允许重复,value 可以重复
(4)HashMap、HashSet 是由底层决定 key 是否相同,TreeMap、TreeSet 是由传入的 Comparator 或实现 Comparable 的 key 决定 key 是否相同
底层
1、无参构造器,根据其元素的自然排序进行排序,所有元素必须实现 Comparable 接口
public TreeSet() {
this(new TreeMap<E,Object>());
}
public TreeMap() {
comparator = null;
}
2、有参构造器,传入比较器(匿名内部类)
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
3、添加 key - value
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
compare(key, key); // type (and possibly null) check
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;
}
(1)判断根节点是否为 null
(2)调用 compare 方法,实际是 key 与自身比较,防止 key 为 null
final int compare(Object k1, Object k2) {
return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
: comparator.compare((K)k1, (K)k2);
}
(3)cpr 即为传入的比较器,以比较器实现的 compare 方法比较 key,直到叶子节点,若 key 不同,成为新的叶子节点,若 key 相同,替换 value
(4)若根据其元素的自然排序进行排序,key 不能为 null
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战