向TreeSet中添加自定义对象的两种比较方法

一、问题分析

对于TreeSet类,假如添加对象的类中不实现Comparable接口重写compareTo方法或者TreesSet创建对象未传入自定义的比较类的话,那么运行时将会报错!
Exception in thread "main" java.lang.ClassCastException: cn.com.clearlight.setframe.set.bean.Student cannot be cast to java.lang.Comparable

下面的类还未实现比较器的接口,运行将会报错.

Student类

package cn.com.clearlight.setframe.set.bean;

import java.util.Objects;

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

    public Student() {
     
    }

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

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

    public String getName() {
     
        return name;
    }

    public int getAge() {
     
        return age;
    }
}

TreeSetForCompare类

package cn.com.clearlight.setframe.set;

import cn.com.clearlight.setframe.set.bean.Student;
import cn.com.clearlight.setframe.set.comparator.ComparatorByName;

import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetForCompare {
     
    public static void main(String[] args) {
     
        TreeSet<Student> ts = new TreeSet<>();
        ts.add(new Student("ac", 1));
        ts.add(new Student("a", 1));
        ts.add(new Student("d", 4));
        ts.add(new Student("d", 4));
        ts.add(new Student("ab", 3));
        ts.add(new Student("ab", 1));

        Iterator<Student> iterator = ts.iterator();

        for (Student s : ts) {
     
            System.out.println(s.getName()+":"+s.getAge());
        }
    }
}

TreeSet作为一种Set,它不允许出现重复元素。TreeSet是用compareTo()来判断重复元素的,而非equals().Student类中不重写equals和hashCode方法,对于添加的元素是否有重复的最终结果并没有影响!因此TreeSet在比较的时候,根本没有调用equals方法!


二、完成比较有两种方法可以实现



1、实现Comparable接口,重写compareTo方法

在自定义的类中实现Comparable接口,重写compareTo()方法即可.

上面Student类需要添加的东西

public class Student implements Comparable<Student> {
     
    @Override
    public int compareTo(Student o) {
     
        // 先根据年龄来排序,若年龄相同,则根据String类型中实现的compareTo方法进行排序
        int temp = this.age - o.age;
        return temp == 0 ? this.name.compareTo(o.name) : temp;
    }
}

TreeSetForCompare类的输出结果

a:1
ab:1
ac:1
ab:3
d:4


2、写比较类实现Comparator方法

  1. 新建一个类,实现Comparator类,并重写compare(T o1, T o2)
  2. TreeSetForCompare类中在创建TreeSet对象时,传入参数对此 set 进行排序的比较器

新建的ComparatorByName类

package cn.com.clearlight.setframe.set.comparator;

import cn.com.clearlight.setframe.set.bean.Student;

import java.util.Comparator;

public class ComparatorByName implements Comparator<Student> {
     


    @Override
    public int compare(Student o1, Student o2) {
     
    	// 先根据名字来排序,若名字相同,则根据年龄的大小来排序
        int temp = o1.getName().compareTo(o2.getName());
        return temp==0 ? o1.getAge()-o2.getAge() : temp;
    }
}

修改的TreeSetForCompare类

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

TreeSetForCompare类的输出结果

a:1
ab:1
ab:3
ac:1
d:4

三、总结

对于TreeSet类添加自定义对象时,可以通过两种方法来完成比较。

你还需要知道的是,如果同时实现这两种方法的话,第二种方法的优先级高于第一种方法,
即将会按照自定义的比较器的比较方法进行比较!

你可能感兴趣的:(#,Java基础知识,TreeSet,比较方法)