对类实现整体排序须使用Comparable接口
看如下错误:
Exception in thread “main” java.lang.ClassCastException: class_chapter.StudentExample cannot be cast to java.lang.Comparable
使用TreeSet存储对象是其自带一定规则的排序方法,但对复杂的对象排序须使用Comparable不然会吹西安上面的错误。
comparable是一个接口,其中compareTo()方法定义了排序规则,可以对复杂的对象进行排序。
代码部分:
//测试类
public class ComparableChapter {
public static void main(String[] args) {
TreeSet<StudentExample> ts=new TreeSet<StudentExample>();
StudentExample s1=new StudentExample("s001","小明","男",20,95);
StudentExample s2=new StudentExample("s002","小王","男",20,90);
StudentExample s3=new StudentExample("s003","小花","女",21,93);
ts.add(s1);
ts.add(s2);
ts.add(s3);
for(StudentExample st1:ts) {
System.out.println(st1);
}
}
//学生类
public class StudentExample{
private String id;
private String name;
private String sex;
private int age;
private double grade;
public String toString() {
return id+"\t\t"+name+"\t\t"+sex+"\t\t"+age+"\t\t"+grade;
}
public void setId(String id) {
this.id=id;
}
public String getId() {
return this.id;
}
public void setNmae(String name) {
this.name=name;
}
public String getNmae() {
return this.name;
}
public void setSex(String sex) {
this.sex=sex;
}
public String getSex() {
return this.sex;
}
public void setAge(int age) {
this.age=age;
}
public int getAge() {
return this.age;
}
public void setGrade(double grade) {
this.grade=grade;
}
public double getGrade() {
return this.grade;
}
public StudentExample() {
}
public StudentExample(String id,String name,String sex,int age,double grade) {
this.id=id;
this.name=name;
this.sex=sex;
this.age=age;
this.grade=grade;
}
}
由于未使用Comparable接口,会出现错误:Exception in thread “main” java.lang.ClassCastException: class_chapter.StudentExample cannot be cast to java.lang.Comparable
// 使用Comparable接口的学生类
public class StudentExample implements Comparable{ //实现Comparable类
private String id;
private String name;
private String sex;
private int age;
private double grade;
public String toString() {
return id+"\t\t"+name+"\t\t"+sex+"\t\t"+age+"\t\t"+grade;
}
public void setId(String id) {
this.id=id;
}
public String getId() {
return this.id;
}
public void setNmae(String name) {
this.name=name;
}
public String getNmae() {
return this.name;
}
public void setSex(String sex) {
this.sex=sex;
}
public String getSex() {
return this.sex;
}
public void setAge(int age) {
this.age=age;
}
public int getAge() {
return this.age;
}
public void setGrade(double grade) {
this.grade=grade;
}
public double getGrade() {
return this.grade;
}
public StudentExample() {
}
public StudentExample(String id,String name,String sex,int age,double grade) {
this.id=id;
this.name=name;
this.sex=sex;
this.age=age;
this.grade=grade;
}
@Override
public int compareTo(java.lang.Object o) { //重写compareTo方法
// TODO Auto-generated method stub
return 1; //1表示第二个对象比前一个打,0表示其相等,-1表示比前一个小
}
}
由于实现了Compareble类就可以正常打印了,并按照输入的顺序输出,如果重写的compareTo()方法返回-1就会逆序输出,返回0只会输出一个,其认为后面和前面的相同。
对类的属性实现整体排序使用Comparator接口
上面的Comparable实现了TreeSet存储对象的整体排序,那如果想根据存储对象的属性的大小对对象进行排序呢?这里要使用Comparator接口。
Comparator是一个类,compare()方法定义复杂的排序机制,来实现排序。
代码部分:
//测试类
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
import class_chapter.Student;;
public class ComparatorChapter {
public static void main(String[] agrs) {
Comparator<Student> comparator=new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// TODO Auto-generated method stub
int figture1=Integer.parseInt(o1.getSid().substring(1)); //定义的学号是S001类型要比较大小截取S后面的部分,再转化未int类型
int figture2=Integer.parseInt(o2.getSid().substring(1));
int sum=figture1-figture2;
int s=sum==0? o1.compareTo(o2) : sum; //comparaTo()方法通过返回值来排序,三元表达式,判断学号的差值是否等于0,两种表达式。
return s; //Comparator的compare()方法和compareTo()方法一样都是通过返回值来改变排序机制,1,0,-1
} //这里返回o1.compareTo(o2)式从小大排序,如果不等于0,是负数就比上一个小,排在前面,是正数就不上一个大在后面
};
Student s3=new Student("s003","小王");
Student s2=new Student("s002","小张");
Student s1=new Student("s001","小李");
TreeSet ts1=new TreeSet(comparator); //再创建TreeSet是需要引入Comparetor对象,对TreeSet的对象排序
ts1.add(s3);
ts1.add(s2);
ts1.add(s1);
Iterator Iterator = ts1.iterator();
while(Iterator.hasNext()) {
System.out.println(Iterator.next());
}
}
}
//学生类
public class Student{
private String sid;
private String sname;
public String toString() { //注意当是String类型是一定要重写tostring方法不然输出collection_and_map.Teacher@7852e922
return sid+" "+sname;
}
public void setSid(String sid) {
this.sid=sid;
}
public String getSid() {
return this.sid;
}
public void setSname(String sname) {
this.sname=sname;
}
public String getSname() {
return this.sname;
}
public void Student() {
}
public Student(String sid,String sname) {
this.setSid(sid);
this.setSname(sname);
}
public int compareTo(Student o2) {
// TODO Auto-generated method stub
return 1; //该方法为collection_and_map的ComparatorChapter类重写,并调用,详情见StudentExanple类
//返回1,后面比前面打排在当前对象的后面,-1表示小,0表示相等。
}
}
运行结果:
可以看到,添加到TreeSet中的顺序有s1,s2,s3;而输出顺序却相反,原因是创建TreeSet时引入了Comparator
改变了排序规则,使从小到大排序。
值得关注的是,Comparable,和Comparator的作用都是排序,但作用对象却不一样。他们都重写了compareTo()方法。所以要熟悉该方法。Comparator还重写了compare()方法,定义了排序规则,两个方法类似注意区分。引入comparator对象可以使用匿名内部类的方法,会更简洁。
代码:TreeSet<Student> ts2=new TreeSet<Student>(new Comparator<Student>() { @Override public int compare(Student stu1, Student stu2) { // TODO Auto-generated method stub int figture1=Integer.parseInt(stu1.getSid().substring(1)); int figture2=Integer.parseInt(stu2.getSid().substring(1)); int sum=figture1-figture2; int s=sum==0? stu1.compareTo(stu2) : sum; return s; } }); //完整语句要有;不然会出错
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/156341.html