Java TreeSet 介绍

怀旧网个人博客网站地址:怀旧网,博客详情:Java TreeSet 介绍

TreeSet 与 其他 Set 集合的区别

  1. TreeSet 存储的数据默认输出是有序的
  2. TreeSet 底层采用的存储数据结构不是数组+链表+红黑树,而是直接采用的红黑树
  3. TreeSet 的去重方式是根据当前的插入的元素和原数据进行比较看是否去重的(比较的规则可以自定义的)

使用测试

创建一 TreeSet 实例

TreeSet<Integer> ts = new TreeSet<>();

像里面添加无序的数据

TreeSet<Integer> ts = new TreeSet<>();

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

System.out.println(ts);

image-20240318093351494

输出结果默认有序


其他类型测试

TreeSet<String> ts = new TreeSet<>();

ts.add("abb");
ts.add("aab");
ts.add("ab");

System.out.println(ts);

image-20240318093501101

这里的比较规则,是根据底层的字符串自己的比较规则来进行排序的,首先比较第一位,谁小谁在前,后面一次比较其他位置数据,比较的值是根据对应字符在Ascall码表的值来比较的。


自定义数据类型测试

public class Student {
    public String name;
    public int age;

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public static void main(String[] args) {
    TreeSet<Student> ts = new TreeSet<>();

    ts.add(new Student("zhangsan", 5));
    ts.add(new Student("wangwu", 2));
    ts.add(new Student("lisi", 4));

    System.out.println(ts);
}

image-20240318094103946

注意:运行报错

​ 原因: 因为TreeSet底层是采用黑红树的数据结构来进行存储数据,但是这种数据进行存储的时候,必须要是可以进行比较的数据才可以,这边的自定义数据类型,并不能进行谁大谁小的比较,所以会报错。


添加比较规则测试

直接继承Comparable结构,重写compareTo方法来实现比较规则--这边是采用比较年龄大小来进行区分

public class Student implements Comparable<Student>{
    public String name;
    public int age;

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

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

    @Override
    public int compareTo(Student s) {
        return this.age - s.age;
    }
}

再次运行代码

image-20240318094437628

成功输出结果,并且得到升序的数据

TreeSet<Student> ts = new TreeSet<>();

ts.add(new Student("zhangsan", 5));
ts.add(new Student("wangwu", 2));
ts.add(new Student("lisi", 4));

ts.add(new Student("zhaoliu", 4));

System.out.println(ts);

image-20240318095855514

可以从输出结果看出来尽管用户名不用,但是age相同也会触发相同数据不添加。原因是重写的compareTo方法里面是通过age来比较大小的。


第二种实现排序的方法

在对字符串进行比较的时候,它默认是根据自己的规则来进行排序的,但是我目前不相通过它自己的规则,但是有不能改它的源码,所以现在就可以采用第二种规则来进行。(这边的规则设定为,根据字符串的长度来判断,要是长度一样就说明重复)

默认情况:

TreeSet<String> ts = new TreeSet<>();

ts.add("abcd");
ts.add("ab");
ts.add("add");

ts.add("ab");

System.out.println(ts);

image-20240318103015620

没有安装需要的方式来进行-现在使用新方式,自定义排序规则

TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        int i1 = s1.length();
        int i2 = s2.length();

        return i1 - i2;
    }
});

ts.add("abcd");
ts.add("ab");
ts.add("add");

ts.add("ab");

System.out.println(ts);

image-20240318103228687

结果完成预期效果

简写代码:

TreeSet<String> ts = new TreeSet<>((s1, s2) -> s1.length() - s2.length());

ts.add("abcd");
ts.add("ab");
ts.add("add");

ts.add("ab");

System.out.println(ts);

image-20240318103350308

完成最终效果

总结

image-20240318103457398

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值