Java中TreeMap的基本介绍,细节讨论,使用注意事项,常用方法,底层源码的分析

TreeMap 是 Java 中的一个有序映射实现,它基于红黑树数据结构来存储键值对,并且可以根据键的自然顺序或者自定义的比较器来进行排序。下面是关于 TreeMap 的基本介绍、细节讨论、使用注意事项、常用方法以及一些底层实现细节。

基本介绍:

  • TreeMapMap 接口的实现类,它实现了一个有序的键值对集合。
  • TreeMap 中的键是按照其自然顺序或者比较器的顺序进行排序的。
  • TreeMap 不允许存储重复的键,每个键在映射中只能出现一次

细节讨论:

  • TreeMap 会根据键的自然顺序或者自定义的比较器来进行排序。如果键没有实现 Comparable 接口并且没有提供比较器,会在运行时抛出 ClassCastException
  • 添加、删除和查找操作的时间复杂度平均为 O(log n),其中 n 是映射中键值对的数量。
  • TreeMap 不是线程安全的,如果在多线程环境下使用,需要进行适当的同步控制。

使用注意事项:

  • 在使用 TreeMap 时,键需要具有可比较性(可以用instanceOf作为防护机制),要么实现 Comparable 接口,要么在构造 TreeMap 时提供一个比较器
  • 自然顺序是指键的默认顺序,如数字的升序、字符串的字典序等。如果需要不同的顺序,可以通过比较器来实现

常用方法:

  • put(K key, V value): 向映射中添加一个键值对。
  • get(Object key): 获取指定键对应的值。
  • remove(Object key): 从映射中移除指定的键值对。
  • containsKey(Object key): 判断映射是否包含指定的键。
  • isEmpty(): 判断映射是否为空。
  • size(): 返回映射中键值对的数量。
  • clear(): 清空映射中的所有键值对。

底层源码和底层实现:

  • TreeMap 的底层基于红黑树(Red-Black Tree)数据结构来存储键值对。红黑树是一种自平衡的二叉查找树,确保树的高度始终保持在一个相对较小的范围内,从而保证了添加、删除和查找操作的高效性能。
  • 红黑树的特性使得键在树中按照顺序排列,从而实现了 TreeMap 的有序性。
  • 通过自平衡的操作,红黑树能够在插入和删除键值对时自动进行树的重新平衡,从而保持树的结构稳定。

总之,TreeMap 提供了一个有序的键值对映射实现,通过底层的红黑树数据结构实现了高效的键值对存储、添加、删除和查找操作。在需要保持键的顺序的映射场景下,可以使用 TreeMap

TreeMap的底层代码分析:

public class TreeMap_ {
    public static void main(String[] args) {
        //使用默认的构造器,创建 TreeMap, 默认是按自然顺序排序的(升序)
        /*
        要求:按照传入的 k(String) 的长度进行排序
        */
        // TreeMap treeMap = new TreeMap();//默认排序
        TreeMap treeMap = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
        //按照传入的 k(String) 的大小进行排序
        //按照 K(String) 的长度大小排序
        //return ((String) o2).compareTo((String) o1);
                return ((String) o2).length() - ((String) o1).length();
            }
        });
        treeMap.put("ret1", "JACK");
        treeMap.put("tom", "TOM");
        treeMap.put("a", "A");
        treeMap.put("ret", "RET");//加入不了,因为此时是按字符串的长度来排序的,长度和tom相同都为3,但若是在自然排序下是可以插入进去的,因为默认的情况下是比较的两个字符串是否一样而不是比较的长度
        System.out.println("treemap=" + treeMap);

        /*
        源码分析:
        1. 构造器.把传入的实现了Comparator 接口的匿名内部类(对象),传给给 TreeMap 的 comparator
        public TreeMap(Comparator < ? super K > comparator) {
            this.comparator = comparator;
        }
        2. 调用 put 方法
        2.1 第一次添加, 把 k - v 封装到 Entry 对象,放入 root
        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;
        }
        2.2 以后添加
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do { //遍历所有的 key , 给当前 key 找到适当位置
                parent = t;
                cmp = cpr.compare(key, t.key);//动态绑定到我们的匿名内部类的 compare
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else //如果遍历过程中,发现准备添加 Key 和当前已有的 Key 相等,就不添加
                    return t.setValue(value);
            } while (t != null);
        }
*/
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值