我知道它已经被询问和回答了数百万次,但我仍然无法弄清楚为什么我在排序期间收到了违规。这是我的代码:
Collections.sort(sorted, new Comparator<MyObject>() {
@Override
public int compare(MyObject m1, MyObject m2) {
// Actual energy comparison :-
// THE higher the energy, the earlier in the list
float delta = m1.getTotalEnergy() - m2.getTotalEnergy();
if (delta > 0) {
return 1;
} else if (delta < 0) {
return -1;
} else {
return 0;
}
}
});
我收到了这个错误
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:895)
at java.util.TimSort.mergeAt(TimSort.java:512)
at java.util.TimSort.mergeForceCollapse(TimSort.java:453)
at java.util.TimSort.sort(TimSort.java:250)
at java.util.Arrays.sort(Arrays.java:1512)
at java.util.ArrayList.sort(ArrayList.java:1454)
at java.util.Collections.sort(Collections.java:175)
有什么想法吗?
也许这会做出改变:
public int compare(Object m1, Object m2) {
// Actual energy comparison :-
// THE higher the energy, the earlier in the list
float delta = ((MyObject)m1).getTotalEnergy() - ((MyObject)m2).getTotalEnergy();
....
}
没有引用MyObject
。我的猜测是比较器与MyObject.equal
不一致。
也就是说,你违反的合同是:
(comparator.compare(mo1, mo2) == 0) == mo1.equals(mo2)
您的比较器将比较具有相同浮点值的对象作为相等,其中更复杂的比较仪将给出排序,而equals方法将表示对象不相等。或者你可能会遇到相反的问题——equals方法表示对象相等,而compare方法表示对象不同。
以下应该有效。
public int compare(MyObject m1, MyObject m2) {
if (m1 == m2) return 0;
if (m1 == null) return -1;
if (m2 == null) return 1;
if (m1.equals(m2)) return 0;
int value = Float.compare(m1.getTotalEnergy(), m2.getTotalEnergy());
if (value != 0) return value;
// Warning, this line is not fool proof as unequal objects can have identical hash
// codes.
return m1.hashCode() - m2.hashCode();
}
假设getTotalEnergy()
return(s)float
,您可以使用
return new Float(m1.getTotalEnergy()).compareTo(m2.getTotalEnergy());
使用 Float.valueOf(float)
可能效率更高,希望这更容易阅读。
Float f1 = Float.valueOf(m1.getTotalEnergy());
Float f2 = Float.valueOf(m2.getTotalEnergy());
return f1.compareTo(f2);
是的,我知道有很多问题与相同的问题,但我似乎真的找不到我的比较器有什么问题。 所以,这里是: 代码非常简单:我需要根据它们如何改变我的主要结构对一些对象进行排序,并且我首先想要最高值。 由于计算或对象的影响可能需要一些时间,我只是缓存值以便重用它们,因此在排序之前,我检查是否有缓存值或是否需要计算它。 一旦我计算出将< code>m1或< code>m2应用于我的结构的结果,我就将更改恢复。 你可
我有一个类字段,和。我需要使用对它们进行排序,但我得到了一个异常: java.lang.IllegalArgumentException:比较方法违反了它的一般约定! 我的< code>compareTo方法: 请帮我找出compareTo方法中的错误。谢了。
我在尝试对节点的数组列表进行排序时遇到了这个错误。我尝试了大多数解决方案,但没有一个在我的案例中有效。 此代码为 它适用于小输入,但是当输入数量很大时,它会给出这个错误。我也读过比较方法中的传递性规则,但我不知道它是如何在这种情况下应用的。 先谢谢你。
我目前正在Java中对集合进行排序。我收到了错误消息“比较方法违反了它的一般契约”。我也理解这个错误消息,但我(主要)使用Long类型的构建比较方法。所以我不知道,在这种情况下,排序方法仍然违反了契约。这是我的代码: 这里是错误:
从昨天开始,我的代码中出现了错误,我不知道为什么!我用谷歌搜索了很多,找到了这个堆栈帖子。 我使用这个功能按名称对用户进行排序并创建日期。这个功能已经工作了2年,现在我收到一个用户的错误,我不知道发生了什么变化。我试图检查我的数据是否有任何损坏,但找不到任何问题。 读完zhe Stack-Post后,我仍然没有完全理解问题出在哪里,或者我的项目发生了什么变化。
我看到我的应用程序在一些中国 Android 手机上发生了很多崩溃,并出现错误:比较方法违反了其总合同! 我读过这与Collections.sort有关。 我不太确定的是,这是否是因为我的自定义比较器。 以下是错误发生的地方: 比较器是这样的: 所以我不太确定比较器是否搞砸了什么,或者我是否需要以不同的方式进行collections.sort调用 感谢任何帮助