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.
在处理作业时,我发现对于以下代码 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.