集合之TreeSet重写compareto应用

一、TreeSet如何判断对象值是否重复

TreeSet 和HashSet(hashCode和equals两个方法)判断对象值是否重复不同,它是根据compareTo(Objec o)方法判断的 若该方法返回0, 就表示对象相等。

二、为什么默认的TreeSet不需要重写compareto方法?

1、看代码解毒

下面代码中set.add()方法添加的是String类型数据,因String类重写了compareto()方法。所以不需要在重写compareto()

import java.util.Set;
import java.util.TreeSet;

public class ThreeSetDemo {
    public static void main(String[]args){
        //构造一个新的空 set,该 set 根据其元素的自然顺序进行排序
        Set set = new TreeSet();
        //1、传入的是String类型,String类中重写了compareto方法。所以在这里不用重写。
        set.add("1");
        set.add("2");
        set.add("5");
        set.add("4");
        System.out.println(set);

    }
}

 

三、自定义比较器compareto

1、在set.add()方法添加的是一个自定义类对象的时候,由于这个类默认没有实现Comparable接口并重写compareto()方法,所以set在添加这个类对象(set.add(new Person())会抛出没有比较器异常。(java.lang.ClassCastException: day15.Person cannot be cast to java.lang.Comparable)

2、给这自定义类实现Comparable接口并重写compareto()方法

import java.util.Set;
import java.util.TreeSet;

class Person implements Comparable{
    private Integer age;
    public Person(int age){
        this.age = age;
    }

    @Override
    //重写compareTo()
    public int compareTo(Object o) {
        if(o instanceof Person){
            Person p = (Person) o;  //1、将compareTo参数类型转换为Person类型
            if(this.age>p.age){         //2、当前对象引用的age值和compareTo比较器的age值进行比较。前者大于后者则返回1
                return 1;
            }else if(this.age<p.age){   //3、当前对象引用的age值和compareTo比较器的age值进行比较。前者小于后者则返回-1
                return -1;
            }
        }
        return 0;                       //4、两者相等返回0
    }

    //二、重写toString()输出age的值,反之只能输出对象的地址。
    @Override
    public String toString() {
        return this.age + "";
    }
}
public class TreeSetDemo2 {
    public static void main(String[]args){
        Set set = new TreeSet();

        set.add(new Person(12));
        set.add(new Person(18));
        set.add(new Person(13));
        System.out.println(set);

    }
}

3、结果

java 重写按键事件 java compareto重写_比较器

 

四、创建TreeSet构造方法传入比较器

  • 创建TreeSet的时候可以制定 一个Comparator
  • 如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
  • add()方法内部会自动调用Comparator接口中compare()方法排序
  • 调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数

代码示例如下:

1、在代码中创建了一个比较器(MyComparator),实现根据人的年龄倒叙排序。

2、在TreeSet构造方法中传入MyComparator类的对象。

3、TreeSet按照MyComparator比较规则进行排序(根据年龄倒叙排序)

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

class Person2 {
    private Integer age;

    public Person2(int age) {
        this.age = age;
    }

    public Integer getAge() {
        return age;
    }

    public String toString() {
        return this.age + "";
    }
}
    //一、创建一个比较器MyComparator
class MyComparator implements Comparator {
    //在这里写比较规则,根据人的年龄倒叙排序
    public int compare(Object o1, Object o2) {
        Person2 p1 = (Person2) o1;
        Person2 p2 = (Person2) o2;

        if(p1.getAge() > p2.getAge()){
            return -1;
        }else if(p1.getAge() < p2.getAge()){
            return 1;
        }
        return 0;
    }

}
public class ComparetorDemo {
    public static void main(String[]args){
        Set set = new TreeSet(new MyComparator());

        set.add(new Person2(23));
        set.add(new Person2(13));
        set.add(new Person2(03));
        set.add(new Person2(43));
        set.add(new Person2(93));
        System.out.println(set);
    }
}

java 重写按键事件 java compareto重写_比较器_02