【问题标题】:How is Java sorting this ArrayList correctly with a logically-flawed Comparator?Java 如何使用有逻辑缺陷的比较器正确排序这个 ArrayList?
【发布时间】:2020-09-05 00:55:56
【问题描述】:

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

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 只是将给定点(在本例中为原点)的斜率返回到坐标平面上的某个其他点

输出:

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

【问题讨论】:

  • 这只是巧合吗?它是否也对其他点进行了正确排序?
  • 我可以在我的 Java 11 上重现。

标签: java comparator comparable


【解决方案1】:

这是巧合。

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

这是一个有趣的结果。

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

我使用的是 Oracle jdk-11.0.3。

【讨论】:

    猜你喜欢
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多