TreeSet相关笔记

本文详细介绍了Java中的TreeSet集合,包括其特点:唯一性与有序性。内容涉及如何导入和输出integer、string及自定义引用类型数据。在自定义引用类型时,解释了内部比较器的工作原理,通过比较器比较年龄属性实现升序排序。同时讨论了外部比较器的创建和使用,强调了外部比较器需显式声明才能被TreeSet感知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:TreeSet的特点

  1. 唯一(set集合的通用特点)/元素不可重复
  2. 无序的部分:不按照输入数据时候的顺序输出
  3. 有序的部分:会按照升序来帮你输出

二:TreeSet集合中导入数据以及输出

1.integer类型的数据

public static void main(String[] args) {
	TreeSet<Integer> set1 = new TreeSet<>();
	 	set1.add(8);
        set1.add(4);
        set1.add(3);
        set1.add(5);
        System.out.println(set1);//输出为:[3, 4, 5, 8]
}

2.String类型的数据

public static void main(String[] args) {
	TreeSet<String> set1 = new TreeSet<>();
	 	set1.add("eqweqwe");
        set1.add("caewae");
        set1.add("qwads");
        set1.add("aasd");
        System.out.println(set1);//输出为:[aasd, caewae, eqweqwe, qwads]
}

由此可见,对于Integer类型和String类型输出以后,都是会将其自动排序,按照升序的翻方式来将其输出,而且整型是对其数值的大小比较,字符串类型则是按照首字母的以及往后字母的大小来比较

 其原理是由于Integer类中包含了重写Comparable接口的compareTo方法而String也是因为如此,才能够正常的排序输出

那么如果往TreeSet集合中存入自定义的引用类型又会如何呢?

3.自定义引用类型的集合

在这边,先创建一个学生类

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public Student() {
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", height=" + height +
   **加粗样式**             '}';
    }

    @Override
    public int compareTo(Student o) {
        return this.getAge()-o.getAge();
    }
}

可以看出,此类中定义了:
年龄(int age),身高(double height),姓名(String name)三个私有属性

接着:

  1. 将此类实现comparable接口,所以必须将其compareTo方法重写
  2. 并将其泛型险限制为Student,这时候往此方法中传入的形参就必须是student类型了**

最后具体重写方法:(称之为内部比较器)

  1. 如果要比较年龄,则返回的是 this.getAge()-o.getAge();并且返回的类型为int型
  2. 如果要比较身高,则不能直接两者相减,即return this.getHeight()-o.getHeight(),因为身高在这里定义的是double型,所以返回的会是double型,而不是重写比较方法后要求的int型
    这时候可以将两者封装为对象,将其装箱成为Double类
    这时候只要return ((Double)this.getHeight).compareTo((Double)o.getHeight)
    调用的是Double类里面已经重写过的比较方法,非常方便

4.自定义类型对TreeSet的输入与输出

这时候整个自定义类就完成了,TreeSet集合可以正常的输入这个类的数据,并且可以正常升序输出元素了,至于按照三个私有属性,按照哪个属性来升序输出,只需要在比较器里比较哪个属性即可

例如:我Student类中内部比较器里面,比较的是age属性,并且返回的是
this.getAge()-o.getAge,

那么我此刻往TreeSet中添加学生类

 TreeSet<Student> set1 = new TreeSet<>();
  set1.add(new Student(17,"zhangsan",98.8));
  set1.add(new Student(15,"wangwu",96.7));

那么我这时候输出的会是,对年龄进行排序后的结果,且为升序顺序
那么因为王五的年龄比张三小,则一定会第一个输出,结果为:

[Student{age=15, name=‘wangwu’, height=96.7}, Student{age=17, name=‘zhangsan’, height=98.8}]

值得注意的是,因为我们要比较的是年龄属性,则如果年龄属性重复的话,因为TreeSet集合的唯一性原则,则只会输出一个,而不会全部输出
例如:

TreeSet<Student> set1 = new TreeSet<>();
  set1.add(new Student(17,"zhangsan",98.8));
  set1.add(new Student(17,"wangwu",96.7));

这时候只会输出张三

而如果年龄不同,名字相同,身高相同也是可以正常输出的,因为我们比较的只是身高

TreeSet<Student> set1 = new TreeSet<>();
  set1.add(new Student(17,"zhangsan",98.8));
  set1.add(new Student(15,"zhangsan",98.8));

这样的话依旧是会正常输出两个元素

以上讲的是内部比较器,而且TreeSet集合默认使用的是内部比较器,如果此时我们没定义内部比较器,则TreeSet搜索不到内部比较器,则被判定为无法正常输出,则会报错,这时候我们就需要定义一个外部比较器

新建一个外部比较器类,并且命名为MyCompare

public class MyCompare01 implements Comparator<Student>{

    @Override
    public int compare(Student o1, Student o2) {
        
        return ((Double)o1.getHeight()).compareTo((Double) o2.getHeight());
    }
}

此类实现的是Comparator接口,并且泛型定义的也是student,重写其compare方法后,这个外部比较器就构建完成了!!!!!!!

现在问题是,TreeSet只能感知到内部比较器,因此外部比较器需要声明一下才能正常使用

  1. 新建一个比较器对象
main
 Comparator<Stuent> com=new MyCompare();
 TreeSet<Student ts=new TreeSet<>(com)
 

这时候即可正常使用外部构造器,并且正常输入输出

2.或者不用新建一个类作为外部比较器也可以,因为有匿名内部类

main{
Comparator<Student> mycomparator =new Comparator<Student>(){
@override
pubulic int compare(Student o1,Student o2){
 return o1.getAge-o2.getAge;
}
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值