java 类的对象比较大小以及排序实现方式

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的使用哈。


 
  

你可能感兴趣的:(Java)