Java error: Comparison method violates its general contract

前端 未结 10 2398
别跟我提以往
别跟我提以往 2020-11-22 04:17

I saw many questions about this, and tried to solve the problem, but after one hour of googling and a lots of trial & error, I still can\'t fix it. I hope some of you ca

10条回答
  •  猫巷女王i
    2020-11-22 05:10

    You can use the following class to pinpoint transitivity bugs in your Comparators:

    /**
     * @author Gili Tzabari
     */
    public final class Comparators
    {
        /**
         * Verify that a comparator is transitive.
         *
         * @param         the type being compared
         * @param comparator the comparator to test
         * @param elements   the elements to test against
         * @throws AssertionError if the comparator is not transitive
         */
        public static  void verifyTransitivity(Comparator comparator, Collection elements)
        {
            for (T first: elements)
            {
                for (T second: elements)
                {
                    int result1 = comparator.compare(first, second);
                    int result2 = comparator.compare(second, first);
                    if (result1 != -result2)
                    {
                        // Uncomment the following line to step through the failed case
                        //comparator.compare(first, second);
                        throw new AssertionError("compare(" + first + ", " + second + ") == " + result1 +
                            " but swapping the parameters returns " + result2);
                    }
                }
            }
            for (T first: elements)
            {
                for (T second: elements)
                {
                    int firstGreaterThanSecond = comparator.compare(first, second);
                    if (firstGreaterThanSecond <= 0)
                        continue;
                    for (T third: elements)
                    {
                        int secondGreaterThanThird = comparator.compare(second, third);
                        if (secondGreaterThanThird <= 0)
                            continue;
                        int firstGreaterThanThird = comparator.compare(first, third);
                        if (firstGreaterThanThird <= 0)
                        {
                            // Uncomment the following line to step through the failed case
                            //comparator.compare(first, third);
                            throw new AssertionError("compare(" + first + ", " + second + ") > 0, " +
                                "compare(" + second + ", " + third + ") > 0, but compare(" + first + ", " + third + ") == " +
                                firstGreaterThanThird);
                        }
                    }
                }
            }
        }
    
        /**
         * Prevent construction.
         */
        private Comparators()
        {
        }
    }
    

    Simply invoke Comparators.verifyTransitivity(myComparator, myCollection) in front of the code that fails.

提交回复
热议问题