【从零开始学Java | 第二十五篇】TreeSet

目录

前言

一、TreeSet的特点

二、TreeSet集合默认的规则

1.默认排序/自然排序

2.比较器排序

总结


前言

在 Java 的集合框架中,Set 接口代表了一个不允许存在重复元素的集合。我们最常用的通常是 HashSet,因为它提供了极高的查找和插入效率。但是,当我们不仅需要去重,还需要保证集合元素有序时,TreeSet 就成了不二之选。

一、TreeSet的特点

  • 不重复、无索引、可排序
  • 可排序:按照元素的默认规则(由小到大)进行排序。
  • TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都比较好。

排序的具体场景:

java 复制代码
public class Test {
    public static void main(String[] args) {
        TreeSet<Integer> ts = new TreeSet<>();

        ts.add(5);
        ts.add(3);
        ts.add(2);
        ts.add(1);
        ts.add(4);

        System.out.println(ts);

        //迭代器遍历
        Iterator<Integer> it = ts.iterator();
        while(it.hasNext()){
            int i = it.next();
            System.out.println(i);
        }
        //增强for遍历
        for (Integer i : ts) {
            System.out.println(i);
        }

        //Lambda表达式遍历
        ts.forEach(integer-> System.out.println(integer));
    }
}

二、TreeSet集合默认的规则

  • 对于数值类型:Integer、Double,默认是按照数字的从小到大的顺序进行排序。
  • 对于字符、字符串类型:按照字符在ASCII码表中的数字进行升序排序的。

对于"aaa"、"ab"这两个字符串在对比时,跟字符串的长度是无关的,对比规则为,从第一个字符开始对应比较,一旦有一个字符能够确定大小关系,那么整个字符串的大小关系也随之确定。

1.默认排序/自然排序

JavaBean类实现Comparable接口指定比较规则。

当我们存入引用类型数据时,会发生什么?

Student JavaBean类:

java 复制代码
public class Student {
    private String name;
    private int age;


    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}

当我们直接添加、打印输出时会发生什么?

由于编译器并不知道根据什么来排序,因此会报错。

解决方法:我们需要在Student类中重写compareTo方法。

运行结果:

compareTo方法:

this:表示当前要添加的元素。

o:表示已经存在于红黑树的元素。

返回值:

负数:认为要添加的元素是小的,存左边。

正数:认为要添加的元素是大的,存右边。

0:认为要添加的元素已经存在,舍弃。

2.比较器排序

创建TreeSet对象时,传递比较器Comparator指定规则。

java 复制代码
public class Test {
    public static void main(String[] args) {
        TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return 0;
            }
        });
    }
}

案例:

存入字符串"c"、"ab"、"df"、"qwer",按照长度排序,如果一样长则按照首字母排序。

java 复制代码
public class Test {
    public static void main(String[] args) {
        TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                //按长度排序
                int i = o1.length() - o2.length();
                int result = i == 0 ? o1.compareTo(o2) : i;
                return result;
            }
        });

        ts.add("c");
        ts.add("ab");
        ts.add("qwer");
        ts.add("df");
        System.out.println(ts);
    }
}

运行结果:

总结

TreeSet集合的特点

  • 可排序、不重复、无索引
  • 底层基于红黑树实现排序,增删改查性能好

TreeSet集合自定义排序规则

  • 方式一:JavaBean类实现Comparable接口,指定比较规则。
  • 方式二:创建集合时,自定义Comparator比较器对象,指定比较规则。

方法返回值的特点

  • 负数:认为要添加的元素是小的,存左边。
  • 正数:认为要添加的元素是大的,存右边。
  • 0:认为要添加的元素已经存在,舍弃。

😎🤗

相关推荐
Flittly2 小时前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
小兔崽子去哪了2 小时前
Java 生成二维码解决方案
java·后端
人活一口气7 小时前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP9 小时前
Vibe Coding -- 完整项目案例实操
java
荣码9 小时前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
SimonKing9 小时前
Google第三方授权登录
java·后端·程序员
明月光8189 小时前
从一行 @Builder 说起:重新拾起 Java 的 Lombok、注解与 Builder 模式
java
考虑考虑18 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯19 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路1 天前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java