向TreeSet中添加自定义对象的两种比较方法
原创
©著作权归作者所有:来自51CTO博客作者ClearlightY的原创作品,请联系作者获取转载授权,否则将追究法律责任
一、问题分析
对于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方法
- 新建一个类,实现Comparator类,并重写compare(T o1, T o2)
- 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<Student> ts = new TreeSet<>(new ComparatorByName());
TreeSetForCompare类的输出结果
a:1
ab:1
ab:3
ac:1
d:4
三、总结
对于TreeSet类添加自定义对象时,可以通过两种方法来完成比较。
你还需要知道的是,如果同时实现这两种方法的话,第二种方法的优先级高于第一种方法,
即将会按照自定义的比较器的比较方法进行比较!