Java 如何使用逻辑上有缺陷的比较器正确排序此 ArrayList?

How is Java sorting this ArrayList correctly with a logically-flawed Comparator?

在处理作业时,我发现对于以下代码 Java 正确排序我的 ArrayList 点(给定比较器中的条件),在 SlopeOrder 比较方法中使用或不使用第二个 if 语句. Java 被告知只要 a > b 两个点就相等时,Java 怎么可能正确地对这些点进行排序?

public class Point implements Comparable<Point>
{
   ...

   public Comparator<Point> slopeOrder() 
   {
       return new SlopeOrder();
   }

   private class SlopeOrder implements Comparator<Point> 
   {
      public int compare(Point o1, Point o2) 
      {
         double a = slopeTo(o1);
         double b = slopeTo(o2);
         if (a < b) return -1;
         if (a > b) return +1; // <--- Can be removed and list will still be sorted correctly
         return 0;
      }
   }

   ...

   public static void main(String[] args)
   {
      ArrayList<Point> points = new ArrayList<Point>();

      points.add(new Point(1,1));
      points.add(new Point(4,6));
      points.add(new Point(6,6));
      points.add(new Point(3,9));
      points.add(new Point(0,0));
      points.add(new Point(5,2));

      Point origin = new Point(0,0);
      Collections.sort(points, origin.slopeOrder());
      System.out.println(points);
   }
}

注意:slopeTo 只是 returns 给定点(本例中为原点)到坐标平面上其他点的斜率

输出:

[(0, 0), (5, 2), (1, 1), (6, 6), (4, 6), (3, 9)]

真巧

我试过在你的列表中随机添加 100 个点。已排序列表中的前十几个或更多已正确排序,但在 (1, 9)、(0, 3) 之后开始了一个新的排序序列 (4, 0)、(7, 1) 等。整个排序列表仅包含 4 个子序列,每个子序列都已正确排序。

这是一个有趣的结果。

你有缺陷的比较器 returns 0 在某些情况下不应该。 0 使这些元素保持原样。所以它本身并不能保证错误的排序顺序。

我用的是 Oracle jdk-11.0.3.