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

😎🤗

相关推荐
澈2072 小时前
C++并查集:高效解决连通性问题
java·c++·算法
郝学胜-神的一滴3 小时前
Qt 入门 01-01:从零基础到商业级客户端实战
开发语言·c++·qt·程序人生·软件构建
测试员周周3 小时前
【Appium 系列】第06节-页面对象实现 — LoginPage 实战
开发语言·前端·人工智能·python·功能测试·appium·测试用例
2401_873479403 小时前
运营活动被薅羊毛怎么防?用IP查询+设备指纹联动封堵漏洞
java·网络·tcp/ip·github
ShiJiuD6668889994 小时前
大事件板块一
java
摇滚侠4 小时前
@Autowired 和 @Resource 的区别
java·开发语言
Wy_编程4 小时前
go语言中的结构体
开发语言·后端·golang
SeaTunnel4 小时前
(八)收官篇 | 数据平台最后一公里:数据集成开发设计与上线治理实战
java·大数据·开发语言·白鲸开源
大卡片5 小时前
C++的基础知识点
开发语言·c++
吴声子夜歌5 小时前
Java——线程的基本协作机制
java·线程协作