java中类的对象比较大小进行排序,不像C++那样可以重载运算符比较大小,java中需要实现特定的接口或者自己给类加上逻辑大小比较函数,个人认为有以下三种方式吧:
一、类实现java.util.Comparator
Comparator中有个接口,如下:
int compare(T o1, T o2);
比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
举个栗子:
有一个Person类,需要根据年龄比较大小或者排序,可以实现Comparator接口如下:
import java.util.Comparator;
public class Person implements Comparator {
private int age;
private String name;
public Person(){
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
public static void main(String [] args){
Person p1 = new Person(27, "LiuBei");
Person p2 = new Person(25, "ZhangFei");
Person p3 = new Person(26, "GuanYu");
System.out.println(p1.compare(p1,p2));
System.out.println(p1.compare(p2,p3));
}
}
输出结果如下:
2
0
-1
可以根据返回结果int值得正负性判断对象的逻辑大小。
二、类实现java.lang.Comparable
public int compareTo(T o);
含义与上面Comparator接口中的int compare(T o1, T o2)一样,也是根据返回值正负性判断两个对象的大小,
仍以上面的例子展示:
public class Person implements Comparable{
private int age;
private String name;
public Person(){
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Person o) {
return this.age - o.getAge();
}
public static void main(String [] args){
Person p1 = new Person(27, "LiuBei");
Person p2 = new Person(25, "ZhangFei");
Person p3 = new Person(26, "GuanYu");
System.out.println(p2.compareTo(p1));
System.out.println(p1.compareTo(p1));
System.out.println(p1.compareTo(p3));
}
}
输出结果如下:
-2
0
1
跟上面一样,也是根据方法返回值的正负性判断对象的逻辑大小。
三、自己在类中增加比较方法,其实与上面两种思想差不多,如下:
public class Person {
private int age;
private String name;
public Person(){
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int compareTo(Person o) {
return this.age - o.getAge();
}
public static void main(String [] args){
Person p1 = new Person(27, "LiuBei");
Person p2 = new Person(25, "ZhangFei");
Person p3 = new Person(26, "GuanYu");
System.out.println(p2.compareTo(p1));
System.out.println(p1.compareTo(p1));
System.out.println(p1.compareTo(p3));
}
}
可以自己在类中加一个compareTo(Person o)方法,但是一般不推荐这样做,因为像TreeMap等有序集合,在使用key进行排序时,一般都是按照前两种方式要求key类必须实现Comparable接口或者提供key类的Comparator比较器,我们自己写的比较函数,在TreeMap中是不起作用的。如下,按照第三种这样写,是会报异常的:
import java.util.TreeMap;
public class Person {
private int age;
private String name;
public Person(){
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int compareTo(Person o) {
return this.age - o.getAge();
}
public static void main(String [] args){
Person p1 = new Person(27, "LiuBei");
Person p2 = new Person(25, "ZhangFei");
Person p3 = new Person(26, "GuanYu");
TreeMap map = new TreeMap();
map.put(p1,"LiuBei");
}
}
程序运行结果:
Exception in thread "main" java.lang.ClassCastException: Person cannot be cast to java.base/java.lang.Comparable
at java.base/java.util.TreeMap.compare(TreeMap.java:1291)
at java.base/java.util.TreeMap.put(TreeMap.java:536)
at Person.main(Person.java:40)
改成第一种或者第二种,就可以了,以第二种方式为例如下:
import java.util.TreeMap;
public class Person implements Comparable{
private int age;
private String name;
public Person(){
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Person o) {
return this.age - o.getAge();
}
public static void main(String [] args){
Person p1 = new Person(27, "LiuBei");
Person p2 = new Person(25, "ZhangFei");
Person p3 = new Person(26, "GuanYu");
TreeMap map = new TreeMap();
map.put(p1,"LiuBei");
map.put(p2,"ZhangFei");
map.put(p3,"GuanYu");
System.out.println(map);
}
}
程序的输出结果为:
{Person@13b6d03=ZhangFei, Person@f5f2bb7=GuanYu, Person@73035e27=LiuBei}
这样就输出正确的人物顺序了,此例中的自然顺序是按照年龄递增的,没有问题。
第二种构造比较器的方式,大家可以自己亲自动手试一下TreeMap的使用哈。