我正在尝试用java编写一个tiebreaker方法,它将基于 Comparator
. 这是抽象方法:
protected abstract Comparator<Map.Entry<Team, Stats>> getLeagueTableEntryComparator();
现在我想根据得分,然后是进球差距,然后是进球得分来划分条目。下面是一个单独类中的override方法,通过适当的字段进行比较:
@Override
protected Comparator<Map.Entry<Team, Stats>> getLeagueTableEntryComparator() {
return (Map.Entry<Team, Stats> teamStatsEntryOne, Map.Entry<Team, Stats> teamStatsEntryTwo) -> {
int compare = Integer.compare(teamStatsEntryOne.getValue().getPoints(),
teamStatsEntryTwo.getValue().getPoints());
if (compare == 0) {
compare = Integer.compare(teamStatsEntryOne.getValue().getTotalGoalDifference(),
teamStatsEntryTwo.getValue().getTotalGoalDifference());
if (compare == 0) {
compare = Integer.compare(teamStatsEntryOne.getValue().getGoalsFor(),
teamStatsEntryTwo.getValue().getGoalsFor());
}
return compare;
};
}
}
然而,很明显,这是有可能的 compare
即使在比较了每个字段之后,最后也是零。
我的问题是-如果 comparator=0
最后?我是否需要在末尾编写一个数字生成器来实现两个条目之间的“真”随机50/50选择?
3条答案
按热度按时间nfg76nw01#
compare = 0
平均对象是相等的,不需要交换它们(在排序中)lztngnrs2#
如果比较器返回0,则这两个条目被认为是等价的。然后由您决定如何使用这些知识-您可以在两个等效元素之间随机选择,或者对每个元素应用相同的处理方法(例如,在本用例中,如果两个团队之间无法区分,您可以决定在他们之间随机选择,宣布他们为共同冠军,甚至决定他们应该玩一个平局游戏)。
请注意,千万不要在比较器的代码中引入随机部分-这将导致比较器的行为不确定,并违反常规比较器约定。
xxb16uws3#
比较器返回0时发生的行为取决于您如何使用比较器。
如果使用比较器对列表进行排序
Collections.sort
或者List.sort
,比较器返回0表示sort
应保持项目的原始顺序。如果要在此场景中随机化顺序,可以使用
Collections.shuffle
在排序前对列表重新排序。这就保证了所有“等价”项目都有同样的机会获得第一名。如果您只有两个项目并且想要比较它们,您可以调用
compare
如果结果为零,则直接以任何方式打破关系。例如,对于随机选择,可以使用Random
班级。