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

TreeSet 是 Java 中的一个有序集合实现,它基于红黑树数据结构来存储元素,可以保持元素的自然顺序(默认情况下升序)或者根据自定义比较器来进行排序。下面是关于 TreeSet 的基本介绍、细节讨论、使用注意事项、常用方法以及一些底层实现细节。

基本介绍:

  • TreeSetSet 接口的实现类,它实现了一个有序的、无重复元素的集合。
  • TreeSet 中的元素是按照其自然顺序或者比较器的顺序进行排序的
  • TreeSet 不允许存储重复的元素,每个元素在集合中只能出现一次。

细节讨论:

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

使用注意事项:

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

常用方法:

  • add(E e): 向集合中添加一个元素。
  • remove(Object o): 从集合中移除指定的元素。
  • contains(Object o): 判断集合是否包含指定的元素。
  • isEmpty(): 判断集合是否为空。
  • size(): 返回集合中元素的数量。
  • clear(): 清空集合中的所有元素。

底层源码和底层实现:

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

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

TreeSet的底层代码分析:

public class TreeSet_ {
    public static void main(String[] args) {
        //1. 当我们使用无参构造器,创建 TreeSet 时,仍然是无序的(存进去的和取出来的顺序不一样),但是取出来的顺序是按自然顺序排序的(自然顺序是指元素的默认顺序,如数字的升序、字符串的字典序等)
        //2. 如果需要不同的顺序,可以通过比较器来实现。如:希望添加的元素,按照字符串的长度来排序
        //3. 使用 TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)
        // 并指定排序规则
        //简单看看源码
        /*
        1. 构造器把传入的比较器对象,赋给了 TreeSet 的底层的 TreeMap 的属性 this.comparator
        public TreeMap(Comparator < ? super K > comparator) {
            this.comparator = comparator;
        }
        2. 在 调用 treeSet.add("tom"), 在底层会执行到
        if (cpr != null) {//cpr 就是我们的匿名内部类(对象)
            do {
                parent = t;
                //动态绑定到我们的匿名内部类(对象)compare
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else //如果相等,即返回 0,这个 Key 就没有加入
                    return t.setValue(value);
            } while (t != null);
        }
        */
//         TreeSet treeSet = new TreeSet();//默认自然排序
        TreeSet treeSet = new TreeSet(new Comparator() {//自定义排序
            @Override
            public int compare(Object o1, Object o2) {
                //下面 调用 String 的 compareTo 方法进行字符串大小比较
                //让加入的元素,按照长度大小排序
                //return ((String) o2).compareTo((String) o1);
                return ((String) o1).length() - ((String) o2).length();
            }
        });
        //添加数据. treeSet.add("jack");

        treeSet.add("ret");//3
        treeSet.add("ret1");
        treeSet.add("a");
        treeSet.add("abc");//3此时这个加不进去,因为此时是按字符串的长度来排序的,长度和tom相同都为3,但若是在自然排序下是可以插入进去的,因为默认的情况下是比较的两个字符串是否一样而不是比较的长度
        System.out.println("treeSet=" + treeSet);
    }
}

你可能感兴趣的:(java,开发语言)