Java - 如果 Return 值为零,比较器如何工作?

Java - How Does Comparator Work If Return Value Is Zero?

我正在尝试在 Java 中编写一个决胜方法,它将 return 基于 Comparator 中的值的条目。这是抽象方法:

protected abstract Comparator<Map.Entry<Team, Stats>> getLeagueTableEntryComparator();

现在我想根据得分、净胜球差和进球数来区分条目。这是单独 class 中的覆盖方法,通过适当的字段进行比较:

@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 选择?

compare = 0表示对象相等,无需交换(排序时)

如果比较器returns为0,则认为这两个条目是等价的。然后由您决定如何处理这些知识——您可以在两个等效元素之间随机选择,或者对每个元素应用相同的处理(例如,在这个用例中,如果两个团队彼此无法区分,您可以决定在他们之间随机选择,宣布他们为 co-champions,甚至决定他们应该玩 tie-breaker 游戏)。

请注意,您永远不应在比较器的代码中引入随机部分 - 这将导致比较器的行为成为 non-deterministic,并违反一般比较器合同。

比较器 returns 0 时发生的行为取决于您如何使用比较器

如果您使用比较器对包含 Collections.sortList.sort 的列表进行排序,则比较器返回 0 意味着 sort 应保留项目的原始顺序。

如果您想在这种情况下随机排列顺序,可以在排序前使用Collections.shuffle 对列表重新排序。这保证了所有“等价”的项目都有相同的机会首先出现。

Collections.shuffle(list);
Collections.sort(list, comparator);
Object winner = list.get(0);

如果您只有两个项目并且想要比较它们,您可以直接调用 compare 并在结果为零时以您想要的任何方式打破平局。例如,对于随机选择,您可以使用 Random class.

的实例
int compare = comparator.compare(a, b);
Random rnd = new Random();
if (compare == 0) {
    if (rnd.nextBoolean()) {
        winner = a;
    } else {
        winner = b;
    }
}