如果我们自定义一个学生类,并实现了两个对象,类中成员属性有姓名,年龄,我们该如何比较呢,先看下面这段代码,自定义了一个学生类
package main;
public class Student {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
然后我们在,main方法中实例化并初始化两个对象
package main;
public class Main {
public static void main(String[] args) {
Student s=new Student("wangcai",11);
Student s1=new Student("cuihua",13);
}
}
此时,我们想比较这两个对象,就得使用到java内置的comparable接口,<>括号中放入要比较的类
package main;
//实现comparable接口
public class Student implements Comparable<Student>{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//重写comparable接口中的compareTo抽象方法,注意这个重写后的方法是根据年龄比较大小的
@Override
public int compareTo(Student o) {
if (this.age<o.age){
return -1;
}
else if (this.age>o.age){
return 1;
}
else{
return 0;
}
}
}
在main方法中,我们这样子写
package main;
public class Main {
public static void main(String[] args) {
Student s=new Student("wangcai",11);
Student s1=new Student("cuihua",13);
System.out.println(s.compareTo(s1));
}
}
,通过运行之后的结果来看,打印了-1,所以这个通过年龄比较两个大小算是成功了。
那么,又如何通过姓名name来比较呢,和通过年龄比较大小有所不同
我们通过改造一下compareTo方法来实现,以下代码改造后的
package main;
//实现comparable接口
public class Student implements Comparable<Student>{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
//重写comparable接口中的compareTo抽象方法,注意这个重写后的方法是根据name比较大小的
@Override
public int compareTo(Student o) {
return this.name.compareTo(o.name);
}
}
,此时,在main方法中,我们就可以通过name来比较对象大小了。不过,我们需要注意几个点:
1.在比较name时,是从字符串的第一个字符开
始比较,如果,s的第一个字符s1第一个字符大,便是s大。输出的是之间ASCII码值的差值。否则,以此往后推,如果全部一样,输出的就是0。
2.这个东西有缺陷,重写方法中比较方式一般用于固定的比较。不适合非常灵活的比较
给对象数组排序
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "[" + this.name + ":" + this.age + "]";
}
}
再给定一个学生对象数组, 对这个对象数组中的元素进行排序(按年龄降序).
Student[] students = new Student[] {
new Student("zhangsan", 20),
new Student("lisi", 26),
new Student("wangwu", 27),
new Student("zhaoliu", 22),
};
按照我们之前的理解, 数组我们有一个现成的 sort 方法, 能否直接使用这个方法呢?
Arrays.sort(students);
System.out.println(Arrays.toString(students));
// 运行出错, 抛出异常.
Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to java.lang.Comparable
仔细思考, 不难发现, 和普通的整数不一样, 两个整数是可以直接比较的, 大小关系明确. 而两个学生对象的大小关系怎么确定? 需要我们额外指定.
//在student类重写comparable接口中的compareTo抽象方法,注意这个重写后的方法是根据年龄大小进行排序的 @Override public int compareTo(Student o) { return this.name.compareTo(o.name); }
这样之后,我们便可以根据年龄大小来对这个对象数组进行排序。那么,是否还有别的方法呢?
我们又引出了comparator接口
package main;
import java.util.Comparator;
//这里重新定义了一个Agecomparator类,根据年龄进行排序
public class Agecomparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age- o2.age;
}
}
main方法中
package main;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Student[] students=new Student[]{
new Student("zhangsan", 20),
new Student("lisi", 26),
new Student("wangwu", 27),
new Student("zhaoliu", 22),
};
Agecomparator agecomparator=new Agecomparator();
//这里直接将数组名和比较方式丢进去,就可以对对象数组排序了
Arrays.sort(students,agecomparator);
String str=Arrays.toString(students);
System.out.println(str);
}
}
[Student{name='zhangsan', age=20}, Student{name='zhaoliu', age=22}, Student{name='lisi', age=26}, Student{name='wangwu', age=27}]
以上就是输出排序后。同理,我们只需要将重写的compare方法改一下,就可以根据name来给对象数组排序。
package main;
import java.util.Comparator;
public class Agecomparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
}
以上,大概就是本节内容。总结一下,我们利用了comparable接口来比较两个对象的大小,根据重写的方法不同来比较不同的属性。对对象数组进行排序,就可以里利用comparator接口了,这里是重新创建了一个类来实现这个接口,并在Array.sort方法中将数组名和比较方式传入