Search code examples
javasortingjava-8comparatorjava-6

Comparator issue when switching to Java 8


I am moving from Java 6 to Java 8 and noticed something peculiar with the Comparator interface. Any insight to this would be very helpful.

When I switch to Java 8, the order of the object is being switched inside the “compare” method and the list sorting fails. I go back to java 6 and it works just fine. Here is a test case that fails for me with Java 8 and passes with Java 6.

public class ComparitorTest {

@Test
public void comparatorTest(){
    Record record1 = new Record("First", false);
    Record record2 = new Record("Second", true);
    List<Record> list = new ArrayList<Record>();

    list.add(record1);
    list.add(record2);


    final Comparator<Object> recordComparator = new Comparator<Object>()
            {
                public int compare( Object o1, Object o2 )
                {
                    Record r1 = (Record) o1;
                    Record r2 = (Record) o2;

                    Boolean isReadonly_R1 = r1.getIsReadOnly();
                    Boolean isReadOnly_R2 = r2.getIsReadOnly();

                if( isReadonly_R1.equals( Boolean.TRUE ) )
                    {
                        return 0;
                    }
                    else
                    {
                        return 1;
                    }
                }
            };
            Collections.sort(list, recordComparator);

            assertEquals(list.get(0).name, "Second");
            assertEquals(list.get(1).name, "First");

}



class Record {
    boolean isReadOnly; 
    String name;

    public Record(String name, boolean value) {
        isReadOnly =value;
        this.name = name;
    }

     boolean getIsReadOnly() {
        return isReadOnly;
    }
}   

}

Any insight you guys on this would be very helpful


Solution

  • Your Comparator isn't a valid Comparator. It only looks at the first item to compare; it ignores the second item. It is incapable of returning a negative number, which means that the first item can never be considered "less than" the second item.

    The algorithm used to sort the list happened to work in Java 6 (it had a 50/50 chance, after all), but the algorithm must have changed between Java 6 and Java 8.

    You will need to fix your Comparator's logic according to the compare method's contract:

    Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

    Additionally, it doesn't need to be a Comparator<Object>. Make it a Comparator<Record>, and the compare method can take Records instead of Objects.