Domanda

Basically I have two comparators (Comparator1 and Comparator2) with slightly different implementations. Both should sort a list in descending order of the lengths of the row's name.

Comparator2 does not seem to work with java7/java8. Comparator1 works always. Both works with java 1.6 implementation or if I set -Djava.util.Arrays.useLegacyMergeSort=true. If the problem exists in Comparator2, java should throw IllegalArgumentException, but no exceptions are thrown.

This is stated in java documentation as "The sorting algorithm used by java.util.Arrays.sort and (indirectly) by java.util.Collections.sort has been replaced. The new sort implementation may throw an IllegalArgumentException if it detects a Comparable that violates the Comparable contract"

Is this a bug in JRE or is there something wrong with Comparator2?

public class Main {

public static void main(String[] args) {
    Row row1 = new Row("AAAA");
    Row row2 = new Row("BBB");
    Row row3 = new Row("CC");
    Row row4 = new Row("D");

    List<Row> list1 = new ArrayList<Row>();
    list1.add(row2);
    list1.add(row3);
    list1.add(row1);
    list1.add(row4);

    System.out.println("Before sorting:");
    System.out.println("");

    print(list1);

    Collections.sort(list1, new Comparator2());

    System.out.println("After sorting with comparator2:");
    System.out.println("");

    print(list1);

    Collections.sort(list1, new Comparator1());

    System.out.println("After sorting with comparator1:");
    System.out.println("");

    print(list1);

}

private static void print(List<Row> list) {
    for (Row row : list) {
        System.out.println(row.name);
    }
}

}

public class Row {

String name;

public Row(String name) {
    this.name = name;
}

public int getLength() {
    return name.length();
}

}

public class Comparator1 implements Comparator<Row> {
@Override
public int compare(Row o1, Row o2) {
    Integer length1 = o1.getLength();
    Integer length2 = o2.getLength();
    return -1 * length1.compareTo(length2);
}
}

public class Comparator2 implements Comparator<Row> {

@Override
public int compare(Row o1, Row o2) {
    int length1 = o1.getLength();
    int length2 = o2.getLength();

    if (length1 < length2) {
        return 1;
    } else if (length2 > length1) {
        return -1;
    } else {
        return 0;
    }

}

}
È stato utile?

Soluzione

The first two conditions in Comparator2 is basically the same :

if (length1 < length2) {
    return 1;
} else if (length2 > length1) {
    return -1;
}

Change the else if to length1 > length2 and it should work.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top