我创建了一个自定义比较器,可以按降序对获胜数进行排序,但我不确定它是如何工作的,有人能解释一下这是如何按降序排序的吗?
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;
}
};
返回值告诉调用方哪个项目“更大”(或者它们是否相等)
1 : numOfWins1 < numOfWins2
0 : numOfWins1 == numOfWins2
-1 : numOfWins1 > numOfWins2
(正1或负1也可以是其他整数,如-2/2,-100/100,任何正/负数)
所以,当你回来的时候:
return numOfWins2 - numOfWins1;
如果 OfWins2,它将是一个正数
如果numOfWins2,则为负数
和0如果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);
}
};
当您仅比较整数字段并且此比较是典型的时,可以使用标准方法 compareTo 从整数类型。
Comparator#compare
方法的目标是什么?
比较其两个参数的顺序。当第一个参数小于、等于或大于第二个参数时,返回负整数、零或正整数。
给定您的< code >(numofwins 2-numofwins 1)公式:
下面是一些示例代码。您可以调整Alice和Carol的构造函数,以查看排序操作。
这段代码使用了一个类的新的compact record
定义。这是Java 16的一个特性。但是使用< code>record与本答案无关。您也可以使用传统的类定义。
package work.basil.example;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Comparing
{
public static void main ( String[] args )
{
Comparing app = new Comparing();
app.demo();
}
private void demo ( )
{
List < FootballClub > clubs =
List.of(
new FootballClub( "Alice" , 25 ) ,
new FootballClub( "Bob" , 7 ),
new FootballClub( "Carol" , 25 )
);
Comparator < FootballClub > sortByWinsDescending = new Comparator < FootballClub >()
{
public int compare ( FootballClub footballClub1 , FootballClub footballClub2 )
{
int numOfWins1 = footballClub1.wins();
int numOfWins2 = footballClub2.wins();
/* Returns the number of goals scored in descending order */
return numOfWins2 - numOfWins1;
}
};
List < FootballClub > sorted = new ArrayList <>( clubs );
sorted.sort( sortByWinsDescending );
System.out.println( "clubs = " + clubs );
System.out.println( "sorted = " + sorted );
}
record FootballClub(String name , Integer wins)
{
}
}
这个代码返回(numOfWins2-numOfWins1);
是那种应该避免的“巧妙”编程。这段代码令人困惑和麻烦。我甚至在写这个答案的时候把自己弄糊涂了。
最好是让对象自己比较。在我的示例代码中,我们使用类Integer
。嗯,Integer
对象已经知道如何比较它们自己。因此,调用Integer#compareTo
。
return footballClub1.wins().compareTo( footballClub2.wins() ) ;
或者,对于代码中所示的整数
基元,调用静态实用工具方法 Integer.compare( int x , int y )
:
int numOfWins1 = footballClub1.getNumOfWins();
int numOfWins2 = footballClub2.getNumOfWins();
/* Returns the number of goals scored in descending order */
return Integer.compare ( numOfWins1 , numOfWins2 ) ;
顺便说一句,我们可以查看OpenJDK源代码,看看这Integer是如何实现的。实现了compare(intx,inty)
方法。它们使用一对嵌套的三元运算符。A<代码>:三元是这样工作的:如果谓词测试为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);
养成编写代码的习惯——这是尽可能简单明了的。人类花在阅读代码上的时间比写代码要多得多。在一个作业中,当您的一个报告生成方法中有一个bug,并且您正在半夜进行调试时,您不想试图确定return numOfWins2-numOfWins1是升序还是降序。
作为奖励,人类可读的简单代码通常更有可能成为Java编译器和运行时优化性能的机会。
为了好玩,在return
语句之前添加这一行,以查看各个比较。
System.out.println( "numOfWins1: " + numOfWins1 + " | numOfWins2: " + numOfWins2 + " | numOfWins2 - numOfWins1: " + ( numOfWins2 - numOfWins1 ) );
提示: 如果你想要升序而不是降序,只需将调用的结果相乘整数#compareTo
或整数比较
,再乘以负 1 (-1
)。这样做会翻转结果的符号,负变为正,正变为负,零保持为零。
return ( -1 * Integer.compare ( numOfWins1 , numOfWins2 ) ) ; // Ascending rather than descending sort order.
正如Ole V.V.所评论的那样,如果您对lambdas和方法引用感到满意,那么可以通过调用Comparator.comparingInt
将整个Comparator
implementation分解为单行解决方案进行升序排序。
Comparator < FootballClub > sortByWinsDescending = Comparator.comparingInt( FootballClub :: wins );
我们上面的例子变得非常短。
package work.basil.example;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Comparing2
{
public static void main ( String[] args )
{
Comparing2 app = new Comparing2();
app.demo();
}
private void demo ( )
{
List < FootballClub > clubs =
List.of(
new FootballClub( "Alice" , 20 ) ,
new FootballClub( "Bob" , 7 ) ,
new FootballClub( "Carol" , 30 )
);
Comparator < FootballClub > sortByWinsDescending = Comparator.comparingInt( FootballClub :: wins );
List < FootballClub > sorted = new ArrayList <>( clubs );
sorted.sort( sortByWinsDescending );
System.out.println( "clubs = " + clubs );
System.out.println( "sorted = " + sorted );
}
record FootballClub(String name , Integer wins)
{
}
}
在我的PriorityQueue中,我有两种类型的客户,即VIP和常规客户。我想先为贵宾服务,再为常客服务。 如果CustomerID<100,则视为VIP。 如果客户是VIP,他会排在队列中VIP部分的最后 更新:我不想排序任何其他列除了VIP。我不想添加“日期”,因为它感觉像是一个黑客,而不是理解Java是如何工作的。
问题内容: 我想用自定义排序顺序在Java中创建一个。字符串排序的键需要根据第二个字符进行排序。这些值也是字符串。 样本图: 问题答案: 您可以像这样使用自定义比较器: 样品: 请注意,这只是假设字符在索引1处有一个字符。 另外,您也可以使用以下比较: 通常,此减法“技巧”是无效的,但在这里可以正常使用,因为减法2 不会溢出。 不过,上面的and 解决方案更具可读性。
我想按字母顺序对字段名列表进行排序,但是我需要在比较器的doCompare方法中包含一个条件,以便如果字段名是“pk”,则始终将其排序到列表的顶部。我所拥有的内容如下,但我不确定我是否采取了正确的方法,特别是reurn值为-1000。对此的任何建议都将不胜感激。
问题内容: 为什么无论什么变量成立,它总是返回?即使使用clank搜索变量,它也会返回相同的结果。我错过了什么吗? 我的数组包含逗号分隔的值,我想在数组元素中的逗号之前基于字符串进行搜索。还有其他简单的解决方案吗?我还制作了一个自定义方法,该方法可以遍历数组并找到字符串,但是我正在寻找其他选择。 问题答案: JavaDoc on 声明必须已对数组进行排序,因此比较器实际上将数组值与搜索字符串进行比
下面的代码片段适用于条件1,但不适用于条件2。
问题内容: 我想为汽车清单开发一个排序演示。我正在使用数据表显示汽车列表。现在实际上我想按汽车颜色对列表进行排序。这里不是按字母顺序排序的。我想使用我的自定义排序顺序,例如先是红色汽车,然后是蓝色,等等。 为此,我尝试使用,但它只允许按字母顺序排序。 因此,任何人都可以指导我实现使用该技术的方法,以便使排序变得更快。 问题答案: 我建议你为汽车颜色创建一个枚举,而不要使用字符串,并且枚举的自然顺序