【发布时间】:2014-10-13 07:46:55
【问题描述】:
我看过很多与此问题相关的帖子,但我执行的每一次桌面检查和我实施的建议都没有帮助。我不知道我是如何违反比较器的合同的。当然,我不经常使用比较器。
我有一个很大的 ArrayList 对象,每次更新都会对它们进行排序,因为它们的位置经常变化。我必须按照从左下角到右上角的顺序渲染这些对象,以保持 2D 程序的“深度”外观。
这是我的比较器:
@Override
public int compare(RenderObject o1, RenderObject o2)
{
//if(o1 == null || o2 == null)
// return 0;
if(o1 == null)
return -1;
else if(o2 == null)
return 1;
//vertices in order top-left, top-right, bottom-right, bottom-left
PointF[] bounds1 = o1.getVertices(),
bounds2 = o2.getVertices();
//if(bounds1 == null || bounds2 == null || bounds1.equals(bounds2))
// return 0;
if(bounds1 == null)
return -1;
else if(bounds2 == null)
return 1;
if(bounds1[0].x >= bounds2[1].x || bounds1[3].y <= bounds2[0].y)
return 1;
else if(bounds1[1].x <= bounds2[0].x || bounds1[0].y >= bounds2[3].y)
return -1;
return o1.getZOrder() < o2.getZOrder() ? 1 : (o1.getZOrder() > o2.getZOrder() ? -1 : 0);
}
谁能解释一下违反合同的地方。我尝试对 o1 和 o2 使用相同的精确顶点进行桌面检查,但无法弄清楚它们是如何不相等的。如果无法帮助我想我将不得不手动实现排序,它可能会更有效,因为并非所有对象都会在每次更新时移动,但我仍然想修复此代码,如果没有其他参考的话。
编辑:这是实际的错误,但它是正确的,所有其他人都停止了这个问题。
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(Unknown Source)
at java.util.TimSort.mergeAt(Unknown Source)
at java.util.TimSort.mergeForceCollapse(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at ....Map.update(Map.java:237)
at ....GameMain.update(GameMain.java:76)
at ....BasicGame.start(BasicGame.java:173)
at ....GameMain.main(GameMain.java:121)
【问题讨论】:
-
如果您无法弄清楚,作为权宜之计,您可以使用某些系统属性关闭此一致性检查。
-
谢谢你,Thilo,这可能对将来有用,因为我真的想忽略这个,让我的渲染人员处理这个!
-
顺便说一句,我真的很喜欢您在问题中提供的详细信息,既清晰又向我们提供了有关您尝试过的内容和所处位置的信息。您正是我们正在寻找的 Stack Overflow 贡献者。我已将此问题发送给我的追随者,因为我希望它可以帮助其他有同样问题的人。
-
谢谢@jmort253 我很感激。我总是尽量记住在 SO 上发帖时打开我的详细设置;)