了解Java中的自定义比较器

了解Java中的自定义比较器,java,comparator,Java,Comparator,我创建了一个自定义的比较器,它按降序排列赢的数量,但我不确定这是如何工作的,有人能解释一下这是如何按降序排列的吗 public static Comparator<FootballClub> sortNumOfWins = new Comparator<FootballClub>() { public int compare(FootballClub footballClub1, FootballClub footballClub2) { in

我创建了一个自定义的比较器,它按降序排列赢的数量,但我不确定这是如何工作的,有人能解释一下这是如何按降序排列的吗

public static Comparator<FootballClub> sortNumOfWins = new Comparator<FootballClub>() {

    public int compare(FootballClub footballClub1, FootballClub footballClub2) {

        int numOfWins1 = footballClub1.getNumOfWins();
        int numOfWins2 = footballClub2.getNumOfWins();

        /*Returns the number of goals scored in  descending order*/
        return numOfWins2 - numOfWins1;
    }
};
publicstaticcomparatorsortnumofwins=newcomparator(){
公共int比较(足球俱乐部足球俱乐部1、足球俱乐部足球俱乐部2){
int numOfWins1=footballClub1.getNumOfWins();
int numOfWins2=footballClub2.getNumOfWins();
/*返回按降序排列的进球数*/
返回numOfWins2-numOfWins1;
}
};
尝试以下代码:

    public static Comparator<FootballClub> sortNumOfWins = new Comparator<FootballClub>() {

    public int compare(FootballClub footballClub1, FootballClub footballClub2) {

        Integer numOfWins1 = footballClub1.getNumOfWins();
        Integer numOfWins2 = footballClub2.getNumOfWins();

        return numOfWins2.compareTo(numOfWins1);
    }
};
publicstaticcomparatorsortnumofwins=newcomparator(){
公共int比较(足球俱乐部足球俱乐部1、足球俱乐部足球俱乐部2){
整数numOfWins1=footballClub1.getNumOfWins();
整数numOfWins2=footballClub2.getNumOfWins();
返回numOfWins2.compareTo(numOfWins1);
}
};
当您仅比较整型字段且此比较是典型比较时,您可以使用标准方法compareTo from integer type.

Comparator#compare
该方法的目标是什么

比较其两个参数的顺序。返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个参数

根据您的
(numOfWins2-numOfWins1)
公式:

  • 对于numOfWins1=30和numOfWins2=20的情况,(20-30)是-10,一个负数。所以第一个应该排在第二个之后
  • 对于numOfWins1=20和numOfWins2=30的情况,(30-20)是 10,一个正数。所以第一个应该排序在第二个之上
  • 对于numOfWins1=25和numOfWins2=25的情况,(25-25)是 0,0。因此,这两个项目是并列排序的
完整示例 下面是一些示例代码。您可以调整Alice和Carol的构造函数,以查看排序的效果

此代码使用类的新紧凑定义。这是Java16的一个特性。但是使用
record
与此答案无关。您也可以使用传统的类定义

package work.basil.example;
导入java.util.ArrayList;
导入java.util.Comparator;
导入java.util.List;
公共类比较
{
公共静态void main(字符串[]args)
{
比较应用程序=新的比较();
app.demo();
}
私有void演示()
{
列出<足球俱乐部>俱乐部=
名单(
新足球俱乐部(“爱丽丝”,25岁),
新足球俱乐部(“Bob”,7岁),
新足球俱乐部(“卡罗尔”,25岁)
);
ComparatorsortByWinsDescending=新的Comparator()
{
公共int比较(足球俱乐部足球俱乐部1、足球俱乐部足球俱乐部2)
{
int numOfWins1=footballClub1.wins();
int numOfWins2=footballClub2.wins();
/*返回按降序排列的进球数*/
返回numOfWins2-numOfWins1;
}
};
列表<足球俱乐部>已排序=新阵列列表(俱乐部);
sorted.sort(sortByWinsDescending);
System.out.println(“clubs=“+clubs”);
System.out.println(“排序=”+排序);
}
记录足球俱乐部(字符串名称,整数获胜)
{
}
}
不推荐 此代码
返回(numOfWins2-numOfWins1)
是一种应该避免的“聪明”编程。这段代码既混乱又麻烦。我甚至在写这个答案的时候把自己弄糊涂了

最好是让对象进行自我比较。在我的示例代码中,我们使用类
Integer
。嗯,
Integer
对象已经知道如何比较它们自己了。打电话吧

或者在代码中看到的
int
原语的情况下,调用静态实用程序方法:

int numOfWins1=footballClub1.getNumOfWins();
int numOfWins2=footballClub2.getNumOfWins();
/*返回按降序排列的进球数*/
返回Integer.compare(numOfWins1、numOfWins2);
顺便说一下,我们可以看看这个方法是如何实现的。它们使用一对嵌套的。一个
?:
三元测试是这样工作的:如果谓词测试为true,则使用
后面的项,否则如果为false,则使用
后面的项

// Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved.
// Excerpt from https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/Integer.java
// See licensing terms in that original file.
return (x < y) ? -1 : ((x == y) ? 0 : 1);

升序 提示:如果您想要升序而不是降序,只需将调用的结果乘以
Integer#compare to
Integer。将
乘以负1(
-1
)。这样做会翻转结果的符号,负变为正,正变为负,零保持为零

return(-1*Integer.compare(numOfWins1,numOfWins2));//升序而不是降序排序。
方法参考 同样,如果您熟悉lambda和方法引用,您可以通过调用将整个
Comparator
实现折叠为单行解决方案,以进行升序排序

Comparatorsortbywinsdensing=Comparator.comparingit(FootballClub::wins);
我们上面的例子变得相当简短

package work.basil.example;
导入java.util.ArrayList;
导入java.util.Comparator;
导入java.util.List;
公共类比较2
{
公共静态void main(字符串[]args)
{
Comparing2应用程序=新的Comparing2();
app.demo();
}
私有void演示()
{
列出<足球俱乐部>俱乐部=
名单(
新足球俱乐部(“爱丽丝”,20岁),
新足球俱乐部(“Bob”,7岁),
新足球俱乐部(“卡罗尔”,30岁)
);
比较仪<足球俱乐部
// Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved.
// Excerpt from https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/Integer.java
// See licensing terms in that original file.
return (x < y) ? -1 : ((x == y) ? 0 : 1);
System.out.println( "numOfWins1: " + numOfWins1 + " | numOfWins2: " + numOfWins2 + " | numOfWins2 - numOfWins1: " + ( numOfWins2 - numOfWins1 ) );
Comparator < FootballClub > sortByWinsDescending = Comparator.comparingInt( FootballClub :: wins );
1 : numOfWins1 < numOfWins2
0 : numOfWins1 == numOfWins2
-1 : numOfWins1 > numOfWins2
return numOfWins2 - numOfWins1;