Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collections.sort comparison method violates its general contract

First of all, sorry for asking a question to this topic again. I'm well aware that there are plenty of questions and answers here. I've read some of them but my problem is that I still cannot figure out what I'm doing wrong. Here is my code:

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;
        }

    });

It seems that I'm just to blind to see my error, so if someone of you could help me out with this, I would be very thankful.

EDIT: What I want to do is to determine if a line is the upper, lower, most left or moste right line in a Coordinate System which has its 0/0 coordinate in the upper left corner. The points are of type double. And here is the Error-Message:

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)
like image 874
Raistlin Avatar asked Dec 05 '25 21:12

Raistlin


1 Answers

This is not a proper ordering.

Consider the first method :

You return 1 if both the y coordinates of the first (left) Point are smaller than the y coordinates of the second (right) Point, and return -1 otherwise.

This means that if you are comparing a Point whose y coords are 4 and 6 to a Point whose y coords are 6 and 4, you'll return -1, regardless of which Point is the first argument, which is equivalent to saying that Point1 "<" Point2 and Point2 "<" Point1, which should only be possible if Point1 "==" Point2.

Your compare method should handle each combination of the relations of lhs.p1.y and rhs.p1.y (<,>,==) and the relations of lhs.p2.y and rhs.p2.y (<,>,==). i.e. you have to cover 9 conditions of the form (lhs.p1.y rel rhs.p1.y && lhs.p2.y rel rhs.p2.y) where rel is <,> or ==.

like image 57
Eran Avatar answered Dec 08 '25 12:12

Eran



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!