Comparable与Comparator接口总结

1.Comparable接口
Arrays类中的sort方法可以对对象数组进行排序,但是对象所属的类必须实现Comparable接口。
下面是一个例子
对象数组按score排序

package com.fu.demo;
import java.util.Arrays;
public class Test {
    
    
    public static void main(String[] args) {
    
    
        A[] a=new A[4];
        a[0]=new A(1,50);
        a[1]=new A(2,90);
        a[2]=new A(4,80);
        a[3]=new A(3,70);
        Arrays.sort(a);
        for (A aa:a) {
    
    
            System.out.println(aa);
        }
    }
}

class A implements Comparable<A>{
    
    
    private int num;
    private double score;

    public A(int num, double score) {
    
    
        this.num = num;
        this.score = score;
    }


    @Override
    public int compareTo(A o) {
    
    
        return Double.compare(score,o.score);
    }

    @Override
    public String toString() {
    
    
        return "A{" +
                "num=" + num +
                ", score=" + score +
                '}';
    }
}

2.Comparator接口
在下面这个例子中,sort对String数组按字典顺序排序。这是因为String实现了Comparable接口,若此时我们需求改变了,我们需要对String按长度排序怎么办?这里我们就可以引入Comparator接口了。

import java.util.Arrays;
import java.util.Date;
public class Test {
    
    
    public static void main(String[] args)  {
    
    
     	 String[] arr={
    
    "bbb","aa","c","dddd"};
        for (String str:arr) {
    
    
            System.out.println(str);
        }
        Arrays.sort(arr);
        for (String str:arr) {
    
    
            System.out.println(str);
        }
    }
}

sort的重载方法的第二个参数是传一个比较器,比较器就是实现了Comparator接口的类的实例。我们来看一个例子,按字符串长度排序。

package com.fu.demo;
import java.util.Arrays;
import java.util.Comparator;

public class Test2 {
    
    
    public static void main(String[] args) {
    
    
        String[] array={
    
    "bbb","aa","c","dddd"};

        for (String str:array) {
    
    
            System.out.println(str);
        }
        Arrays.sort(array,new LengthComparator());
        for (String str:array) {
    
    
            System.out.println(str);
        }
    }
}
//这个类的实例就是比较器
class LengthComparator implements Comparator<String>{
    
    
    @Override
    public int compare(String o1, String o2) {
    
    
        return o1.length()-o2.length();
    }
}

此外,Comparator接口还有很多静态方法。这些静态方法很方便去创建比较器。
静态comparing方法取一个“键提取器”函数,它将类型T映射为一个可比较的类型。对要比较的对象应用这个函数,然后对返回的键完成比较。
下面用静态方法按score排序

package com.fu.demo;
import java.util.Arrays;
import java.util.Comparator;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        A[] a=new A[4];
        a[0]=new A(1,50);
        a[1]=new A(2,90);
        a[2]=new A(4,80);
        a[3]=new A(3,70);
        for (A aa:a) {
    
    
            System.out.println(aa);
        }
        Arrays.sort(a,Comparator.comparing(A::getNum));//按num排序
        for (A aa:a) {
    
    
            System.out.println(aa);
        }
    }
}

class A{
    
    
    private int num;
    private double score;
    public A() {
    
    
    }
    public A(int num, double score) {
    
    
        this.num = num;
        this.score = score;
    }
    public int getNum() {
    
    
        return num;
    }
    public double getScore() {
    
    
        return score;
    }
    @Override
    public String toString() {
    
    
        return "A{" +
                "num=" + num +
                ", score=" + score +
                '}';
    }
}

与手动实现一个Comparator相比,这当然容易得多。而且代码也更清晰。
我们还可以把比较器与thenComparing方法串行起来,来处理比较结果相同的情况。例如:

package com.fu.demo;
import java.util.Arrays;
import java.util.Comparator;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        A[] a=new A[4];
        a[0]=new A(1,50);
        a[1]=new A(3,90);
        a[2]=new A(4,80);
        a[3]=new A(3,70);
        for (A aa:a) {
    
    
            System.out.println(aa);
        }
        Arrays.sort(a,Comparator.comparing(A::getNum).thenComparing(A::getScore));
        //先按num排序,再按score
        for (A aa:a) {
    
    
            System.out.println(aa);
        }
    }
}

class A{
    
    
    private int num;
    private double score;
    public A() {
    
    
    }
    public A(int num, double score) {
    
    
        this.num = num;
        this.score = score;
    }
    public int getNum() {
    
    
        return num;
    }
    public double getScore() {
    
    
        return score;
    }
    @Override
    public String toString() {
    
    
        return "A{" +
                "num=" + num +
                ", score=" + score +
                '}';
    }
}

这些方法有很多变体。可以为comparing和thencomparing方法提取的键指定一个比较器。例如,根据先根据按长度排序,再按字典顺序排序。

package com.fu.demo;
import java.util.Arrays;
import java.util.Comparator;

public class Test2 {
    
    
    public static void main(String[] args) {
    
    
        String[] array={
    
    "bb","aa","c","dddd"};

        for (String str:array) {
    
    
            System.out.println(str);
        }
        Arrays.sort(array,Comparator.comparing(String::length).thenComparing(String::compareTo));
        for (String str:array) {
    
    
            System.out.println(str);
        }
    }
}

先按名字长度排序,再按score排序

package com.fu.demo;
import java.util.Arrays;
import java.util.Comparator;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        A[] a=new A[4];
        a[0]=new A(1,100,"aa");
        a[1]=new A(3,90,"bb");
        a[2]=new A(4,80,"ddddddddd");
        a[3]=new A(3,70,"cccc");
        for (A aa:a) {
    
    
            System.out.println(aa);
        }
        Arrays.sort(a,Comparator.comparing(A::getName,(s,t)->s.length()-t.length()).thenComparing(A::getScore));
        //先按名字长度排序,再按score排序
        for (A aa:a) {
    
    
            System.out.println(aa);
        }
    }
}

class A{
    
    
    private int num;
    private double score;
    private String name;
    public A() {
    
    
    }

    public A(int num, double score, String name) {
    
    
        this.num = num;
        this.score = score;
        this.name = name;
    }

    public String getName() {
    
    
        return name;
    }

    public int getNum() {
    
    
        return num;
    }
    public double getScore() {
    
    
        return score;
    }

    @Override
    public String toString() {
    
    
        return "A{" +
                "num=" + num +
                ", score=" + score +
                ", name='" + name + '\'' +
                '}';
    }
}

还有别的静态方法,Comparator.comparingInt,nullsFirst等,都可以查询api,然后调用就好。

猜你喜欢

转载自blog.csdn.net/changbaishannefu/article/details/112358021