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

😎🤗

相关推荐
Bruce_Liuxiaowei几秒前
Python 实例赋值遮蔽类属性:一个从不报错的静默陷阱
开发语言·python·语法糖
滕州市燕猫虎计算机科技工作室个体工商户7 分钟前
IDEA:Command line is too long
java·ide·intellij-idea
步行cgn38 分钟前
Spring p 命名空间注入详解
java·前端·spring
YatHinLay41 分钟前
MyBatis 流式查询实战:ResultHandler 处理海量数据
java
天天被压力1 小时前
【跨市场数据实战 #08】可转债折价机会怎么筛:3个接口抓比价、列表和实时盘口
java·人工智能·python
aramae1 小时前
MySQL内置函数(7)
开发语言·笔记·后端·mysql·其他
张某布响丸辣2 小时前
附件下载的安全边界:路径白名单、NAS 哨兵文件与 Redis Lua 一次性令牌
java·redis·redis lua·nas哨兵
YatHinLay2 小时前
Spring Boot + Calcite 实现跨库查询
java
酷炫码神3 小时前
MosMos 创意效果与能力边界展示
java
Wang's Blog3 小时前
Java 接入Redis: 使用Jedis操作Redis
java·服务器·redis