TreeSet的自然排序(Comparable) [java]

TreeSet的自然排序(Comparable)

重点知识:

  1. TreeSet中的加入的元素会自动进行排序
  2. TreeSet中只能加入同一个类类型创建出来的对象
    • 因为我们的TreeSet中加入的元素会自动将进行排序,那么到底是如何进行排序的?
    • 我们就是根据TreeSet集合中的元素的某个属性进行排序,这个时候如果集合中的元素是不同类型的对象,这个时候就可能一个对象有的属性而另一个对象没有,这个时候我们就要求TreeSet集合中的存储的元素要是同一个类型的对象
    • 如果我们装入多个类的元素,编译器也不会出错,运行期会出现运行期异常(ClassCastException)类型转化异常
  3. TreeSet要比List查询速度更快
  4. 如果要创建一个由自定义对象构成的TreeSet集合,那么我们的自定义类中就要去实现Comparable接口,或者使用有参构造方法创建TreeSet集合,实参为Comparator接口实现类的对象,这个时候也就是使用Comparator比较器进行排序

什么是自然排序?

通过实现Comparable接口来进行排序就是自然排序

什么是选择排序

通过实现Comparator接口来进行排序就是选择排序

  • 在这里我们先讲述TreeSet集合的自然排序

首先我们要知道我们的TreeSet存储的元素会自动进行排序

那么我们的TreeSet集合是如何进行排序的?

  • 其实TreeSet集合之所以可以进行排序就是因为我们的TreeSet中装入的对象的模板类中实现了Comparable接口,或者实现了Comparable接口
    • 如果TreeSet集合中添加的元素所在类没有进行实现我们的任何一种java比较器,那么这个时候如果我们要在这个TreeSet集合中去添加元素,这个时候就会抛出一个运行时异常(ClassCaseException),这个时候其实底层就是默认调用了这个添加元素类的compareTo()方法,这个时候我们底层存储元素时就将这些元素默认转型为了Object类型的,这个时候我们在TreeSet添加元素的时候我们的时候底层也是和使用了向下转型将我们的Object类型的元素转型为Comparable类型的对象,这个时候因为我们的实际的存储的对象的模板类没有实现Comparable接口,这个时候我们就会出现类型转换异常

如何实现自然排序?

  • 这里我们说我们的自然排序就是实现Comparable接口的方式,只要我们让我们的TreeSet集合中装入的元素模板类实现Comparable接口,然后让我们的重写compareTo()方法就可以了

eg:这里我们举一个例子

  • 这个例子中的Dog2类就是我们TreeSet集合中的元素,这个时候我们就让Dog2类实现Comparable接口并且实现compare()方法
package 集合.set;

import java.util.TreeSet;

public class TreeSetDemo {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet();
        treeSet.add(new Dog2("小黑",2));
        treeSet.add(new Dog2("小白",2));
        treeSet.add(new Dog2("小蓝",2));
        treeSet.add(new Dog2("小绿",2));
        treeSet.add(new Dog2("小紫",2));
        
    }
}

/**
 * 这里我们创建了一个Dog2类,让这个类实现了Comparable接口,然后重写了compareTo()方法,并且重写这个方法是
 * 通过多级排序实现的,第一级是判断name属性的大小,第二级是判断age属性的大小
 * 这个时候我们这个自定义类实现了Comparable接口,这个时候我们这个类创建的对象装入TreeSet中时就不会出现类
 * 型转换异常
 */
class Dog2 implements Comparable{
    private String name;
    private int age;
    public Dog2(){

    }

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

    @Override
    public int compareTo(Object o) {
        Dog2 d = (Dog2)o;
        if(this.name.equals(d.name)){
            return age - d.age;
        }
        return name.compareTo(d.name);
    }
}

为什么这里我们比较时会抛出类型转换异常?

因为在底层是将我们的Object类型的引用(实际为自定义类类型)转型为Comparable类型,这个时候如果我们这个自定义类没有实现Comparable接口,自然就会出现类型转换异常

  • 我们一般的自定义类型的数组和集合在底层都是以Object类型进行存储的

关于TreeSet中判断我们要存储的对象是否重复时:

我们这个时候不是通过equals()方法判断是否重复,也没有使用hashCode()方法进行判断

  • 我们在TreeSet中是使用了Comparable接口中的compareTo()方法或者是使用的Comparator接口中的compare()方法判断的元素是否重复
    • 当我们使用自然排序的方式时,这个时候我们就是通过Comparable接口中的compareTo()方进行判断,如果我们的compareTo()方法的返回值为0,这个时候就表示我们要添加的元素和这个TreeSet集合中的元素重复了
    • 当我们使用定制排序时,这个时候我们就是通过Comparator接口中的compare()方法进行判断,如果这个时候我们的compare()方法的返回值为0,这个时候就表示我们要添加的元素和这个TreeSet集合中的元素重复了
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值