【从零开始学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:认为要添加的元素已经存在,舍弃。

😎🤗

相关推荐
自信150413057597 分钟前
重生之从0开始学习c++之string(上)
开发语言·c++·学习
wangjialelele10 分钟前
从零入门 LangChain:Python 语法详解 + 工具开发 + 结构化输出实战
开发语言·人工智能·python·语言模型·langchain
jinanwuhuaguo12 分钟前
OpenClaw智能体的涌现与异化——复杂系统演化、知识权力重构与文明纪元跃迁(第五篇)
大数据·开发语言·人工智能·重构·安全架构·openclaw
Dillon Dong16 分钟前
【系列主题】拯救 OOM 与构建中断:Next.js 在 Docker 中的静态生成(SSG)避坑指南
开发语言·javascript·docker
AI人工智能+电脑小能手18 分钟前
【大白话说Java面试题】【Java基础篇】第10题:HashMap中的元素是有序存放的吗
java·开发语言·数据结构·后端·面试·哈希算法·哈希表
南境十里·墨染春水23 分钟前
linux学习进展 线程
java·linux·学习
itzixiao24 分钟前
L1-049 天梯赛座位分配(20 分)[java][python][c]
java·开发语言·python
子非鱼@Itfuture34 分钟前
ThreadLocal 是什么?如何用?以及最佳使用场景
java·开发语言·spring
杨凯凡34 分钟前
【024】JVM 参数入门:堆、栈、元空间与典型模板
java·开发语言·jvm
不懒不懒36 分钟前
【PaddleOCR实战指南:图像文字识别、实时摄像头与PyQt5 GUI开发】
开发语言·python