调试“比较方法违反了其总合同!”

时间:2013-08-21 18:20:11

标签: java sorting

我有一个自己的,相对复杂的字符串比较器和一个大的字符串列表(大约100个字符串,已经尝试减少,但问题是不可重现的),在尝试使用Java 7进行排序时,排序它们会产生上述错误。我想,这个规则

if a < b and b < c then a < c

可能会受到侵犯。找出违反合同的样本的最佳方法是什么?

3 个答案:

答案 0 :(得分:4)

好吧,我用蛮力方式做了:3个嵌套循环将3个值相互比较并验证上述规则。现在找到违反规则的示例。

答案 1 :(得分:1)

在compare()方法的开头和equals()/ hashcode()方法中添加调试消息(你正在覆盖它们吗?)

答案 2 :(得分:0)

当面对类似的问题时,深入研究问题并找到违反一般契约的 A、b 和 c 的集合的唯一方法是使用循环。

假设您有一个需要排序的 list 和一个违反其合同的自定义 comparator,您可以使用如下所示的方法找到对象

for (int i = 0; i < list.size(); i ++) {
                for (int j = 0; j < list.size(); j ++) {
                    for (int k = 0; k < list.size(); k ++) {
                        Objects a = list.get(i);
                        Objects b = list.get(j);
                        Objects c = list.get(k);
                        if (comparator.compare(a, b) < 0
                                && comparator.compare(b, c) < 0
                                && comparator.compare(a, c) > 0) {
                            System.out.print(("Error...1");
                            System.out.print((a + ", " + i);
                            System.out.print((b + ", " + j);
                            System.out.print((c + ", " + k);
                        }
                        if (comparator.compare(a, b) > 0
                                && comparator.compare(b, c) > 0
                                && comparator.compare(a, c) < 0) {
                            System.out.print(("Error...2");
                            System.out.print((a + ", " + i);
                            System.out.print((b + ", " + j);
                            System.out.print((c + ", " + k);
                        }
                        if (comparator.compare(a, b) == 0
                                && comparator.compare(b, c) == 0
                                && comparator.compare(a, c) != 0) {
                            System.out.print(("Error...3");
                            System.out.print((a + ", " + i);
                            System.out.print((b + ", " + j);
                            System.out.print((c + ", " + k);

                        }
                            
                    }
                }
            }

这个方法我已经用过很多次了,尤其是当你无法通过检查发现编码中的逻辑错误时。

我还在另一篇文章中找到了这个答案,该文章有一个您可以使用的通用课程

https://stackoverflow.com/a/35000727/4019094