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

😎🤗

相关推荐
小江的记录本2 小时前
【Docker】 Docker 全平台部署(Linux / Windows / MacOS)与 前后端分离项目 容器化方案
java·linux·windows·http·macos·docker·容器
wjs20242 小时前
NumPy 从数值范围创建数组
开发语言
java1234_小锋2 小时前
Java高频面试题:ElasticSearch如何做性能优化?
java·开发语言·elasticsearch·面试
静心观复2 小时前
Lua 脚本是什么
开发语言·lua
m0_651593912 小时前
构建智能SKU系统:编码规则、元数据设计与DDD实战指南
java·大数据·数据库
江沉晚呤时2 小时前
深入理解 Akka.NET:高并发与分布式系统的利器
开发语言·c#·.net
环黄金线HHJX.2 小时前
BaClaw龙虾打字
开发语言·人工智能·算法·编辑器
crack_comet2 小时前
Spring Boot 3.5.11 分离打包(无参数启动+Jar瘦身)完整配置文档
java·spring boot·后端·maven·intellij-idea·jar
echome8882 小时前
Go 语言并发编程:Channel 与 Goroutine 的完美结合
开发语言·后端·golang