Collections.sort 比较方法违反了它的总契约
Collections.sort comparison method violates its general contract
首先,很抱歉又问了这个话题。我很清楚这里有很多问题和答案。我读过其中一些,但我的问题是我仍然无法弄清楚我做错了什么。这是我的代码:
Collections.sort(hLines, new Comparator<Line>() {
@Override
public int compare(Line lhs, Line rhs) {
if ( lhs.p1.y < rhs.p1.y){
if (lhs.p2.y < rhs.p2.y)
return 1;
else
return -1;
}
if (lhs.p1.y > rhs.p1.y){
if (lhs.p2.y > rhs.p2.y)
return -1;
else
return 1;
}
else
return 0;
}
});
Collections.sort(vLines, new Comparator<Line>() {
@Override
public int compare(Line lhs, Line rhs) {
if ( lhs.p1.x < rhs.p1.x){
if (lhs.p2.x < rhs.p2.x)
return 1;
else
return -1;
}
if (lhs.p1.x > rhs.p1.x){
if (lhs.p2.x > rhs.p2.x)
return -1;
else
return 1;
}
else
return 0;
}
});
看来我只是盲目地看到了我的错误,所以如果你们中的任何人能帮助我解决这个问题,我将不胜感激。
编辑:
我想要做的是确定一条线是坐标系中的上线、下线、最左线还是最右线,其 0/0 坐标位于左上角。点的类型为双精度。这是错误消息:
06-03 10:42:22.576: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:22.815: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=1 ext2=0
06-03 10:42:22.848: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=1 ext2=0
06-03 10:42:26.408: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:26.747: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=1 ext2=0
06-03 10:42:26.781: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=1 ext2=0
06-03 10:42:29.474: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:30.613: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:30.646: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:30.874: E/AndroidRuntime(15810): FATAL EXCEPTION: Thread-2592
06-03 10:42:30.874: E/AndroidRuntime(15810): java.lang.IllegalArgumentException: Comparison method violates its general contract!
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.mergeHi(TimSort.java:864)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.mergeAt(TimSort.java:481)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.mergeForceCollapse(TimSort.java:422)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.sort(TimSort.java:219)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.sort(TimSort.java:169)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.Arrays.sort(Arrays.java:2038)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.Collections.sort(Collections.java:1891)
06-03 10:42:30.874: E/AndroidRuntime(15810): at com.example.camera.RectangleDetector.drawLines(RectangleDetector.java:108)
06-03 10:42:30.874: E/AndroidRuntime(15810): at com.example.camera.RectangleDetector.findRectangle(RectangleDetector.java:94)
06-03 10:42:30.874: E/AndroidRuntime(15810): at com.example.camera.MainActivity.onCameraFrame(MainActivity.java:114)
06-03 10:42:30.874: E/AndroidRuntime(15810): at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:387)
06-03 10:42:30.874: E/AndroidRuntime(15810): at org.opencv.android.NativeCameraView$CameraWorker.run(NativeCameraView.java:177)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.lang.Thread.run(Thread.java:838)
这不是正确的顺序。
考虑第一种方法:
如果第一个(左)点的 y 坐标小于第二个(右)点的 y 坐标,则您 return1,否则 return-1。
这意味着如果您将 y 坐标为 4 和 6 的点与 y 坐标为 6 和 4 的点进行比较,您将 return -1,无论哪个点是第一个参数,相当于说 Point1 "<" Point2 和 Point2 "<" Point1,这应该只有在 Point1 "==" Point2.
您的 compare
方法应该处理 lhs.p1.y 和 rhs.p1.y (<
,>
,==
)以及lhs.p2.y和rhs.p2.y的关系(<
,>
,==
)。也就是说,您必须满足形式 (lhs.p1.y rel rhs.p1.y && lhs.p2.y rel rhs.p2.y) 的 9 个条件,其中 rel 是 <
,>
或 ==
.
首先,很抱歉又问了这个话题。我很清楚这里有很多问题和答案。我读过其中一些,但我的问题是我仍然无法弄清楚我做错了什么。这是我的代码:
Collections.sort(hLines, new Comparator<Line>() {
@Override
public int compare(Line lhs, Line rhs) {
if ( lhs.p1.y < rhs.p1.y){
if (lhs.p2.y < rhs.p2.y)
return 1;
else
return -1;
}
if (lhs.p1.y > rhs.p1.y){
if (lhs.p2.y > rhs.p2.y)
return -1;
else
return 1;
}
else
return 0;
}
});
Collections.sort(vLines, new Comparator<Line>() {
@Override
public int compare(Line lhs, Line rhs) {
if ( lhs.p1.x < rhs.p1.x){
if (lhs.p2.x < rhs.p2.x)
return 1;
else
return -1;
}
if (lhs.p1.x > rhs.p1.x){
if (lhs.p2.x > rhs.p2.x)
return -1;
else
return 1;
}
else
return 0;
}
});
看来我只是盲目地看到了我的错误,所以如果你们中的任何人能帮助我解决这个问题,我将不胜感激。
编辑: 我想要做的是确定一条线是坐标系中的上线、下线、最左线还是最右线,其 0/0 坐标位于左上角。点的类型为双精度。这是错误消息:
06-03 10:42:22.576: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:22.815: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=1 ext2=0
06-03 10:42:22.848: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=1 ext2=0
06-03 10:42:26.408: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:26.747: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=1 ext2=0
06-03 10:42:26.781: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=1 ext2=0
06-03 10:42:29.474: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:30.613: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:30.646: E/OpenCV_NativeCamera(15810): CameraHandler::Notify: msgType=4 ext1=0 ext2=0
06-03 10:42:30.874: E/AndroidRuntime(15810): FATAL EXCEPTION: Thread-2592
06-03 10:42:30.874: E/AndroidRuntime(15810): java.lang.IllegalArgumentException: Comparison method violates its general contract!
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.mergeHi(TimSort.java:864)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.mergeAt(TimSort.java:481)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.mergeForceCollapse(TimSort.java:422)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.sort(TimSort.java:219)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.TimSort.sort(TimSort.java:169)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.Arrays.sort(Arrays.java:2038)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.util.Collections.sort(Collections.java:1891)
06-03 10:42:30.874: E/AndroidRuntime(15810): at com.example.camera.RectangleDetector.drawLines(RectangleDetector.java:108)
06-03 10:42:30.874: E/AndroidRuntime(15810): at com.example.camera.RectangleDetector.findRectangle(RectangleDetector.java:94)
06-03 10:42:30.874: E/AndroidRuntime(15810): at com.example.camera.MainActivity.onCameraFrame(MainActivity.java:114)
06-03 10:42:30.874: E/AndroidRuntime(15810): at org.opencv.android.CameraBridgeViewBase.deliverAndDrawFrame(CameraBridgeViewBase.java:387)
06-03 10:42:30.874: E/AndroidRuntime(15810): at org.opencv.android.NativeCameraView$CameraWorker.run(NativeCameraView.java:177)
06-03 10:42:30.874: E/AndroidRuntime(15810): at java.lang.Thread.run(Thread.java:838)
这不是正确的顺序。
考虑第一种方法:
如果第一个(左)点的 y 坐标小于第二个(右)点的 y 坐标,则您 return1,否则 return-1。
这意味着如果您将 y 坐标为 4 和 6 的点与 y 坐标为 6 和 4 的点进行比较,您将 return -1,无论哪个点是第一个参数,相当于说 Point1 "<" Point2 和 Point2 "<" Point1,这应该只有在 Point1 "==" Point2.
您的 compare
方法应该处理 lhs.p1.y 和 rhs.p1.y (<
,>
,==
)以及lhs.p2.y和rhs.p2.y的关系(<
,>
,==
)。也就是说,您必须满足形式 (lhs.p1.y rel rhs.p1.y && lhs.p2.y rel rhs.p2.y) 的 9 个条件,其中 rel 是 <
,>
或 ==
.