Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collections.sort in java 8 is not working as java 6 while comparator returning 0

Recently I updated our application jdk from Java 6 to Java 8 but kept source language level still as Java 6. After change one of our unit tests was failing. I noticed that Collections.sort for LinkedList is working different in Java 8 and Java 6. Even when I am Source Level java 8 with JDk 1.8 I am getting same different behavior. To recreate problem: Defining the enum below:

public enum Weight {
    A(1), B(0), C(0), D(0), E(2);

    public int getWeight() {
        return weight;
    }

    private int weight;

    Weight(int weight) {

        this.weight = weight;
    }

    @Override
    public String toString() {
       return  name() + '(' + weight + ')';
    }
}

and a main Class as below:

public class Main {

    public static void main(String[] args) {
      List<Weight> weightList = new LinkedList<Weight>();
      weightList.add(Weight.A);
      weightList.add(Weight.B);
      weightList.add(Weight.C);
      weightList.add(Weight.D);
      weightList.add(Weight.E);

        Collections.sort(weightList, new Comparator<Weight>() {
            @Override
            public int compare(Weight o1, Weight o2) {
                return o1.getWeight() > o2.getWeight()? 1:0;
            }
        });

        System.out.print(weightList);

    }
}

The output for running the code under Java 6 is: "C:\Program Files\Java\jdk1.6.0_45\bin\java"

[B(0), C(0), D(0), A(1), E(2)]

and output for running code under java 8 is:

"C:\Program Files (x86)\Java\jdk1.8.0_161\bin\java"

[A(1), B(0), C(0), D(0), E(2)]

I changed the type from LinkedList to ArrayList and I am getting the same result but if I am changing the comparator as below then Java 8 is going to sort the array:

Collections.sort(weightList, new Comparator<Weight>() {
            @Override
            public int compare(Weight o1, Weight o2) {
                return o1.getWeight() > o2.getWeight()? 1:-1;
            }
        });

As you see it seems that the java 8 is not sorting the code properly. Is there a bug in Java or am I missing something as usual?

like image 378
Govan Avatar asked Mar 02 '18 14:03

Govan


People also ask

Does Collections sort use comparator?

Comparator interface When we want to define an ordering for sorting the objects of some type T, we can create a custom Comparator, which we can pass in our Collections. sort() method as the second argument while sorting List<T> list.

How does Java sort with comparator?

In Java, we can implement whatever sorting algorithm we want with any type. Using the Comparable interface and compareTo() method, we can sort using alphabetical order, String length, reverse alphabetical order, or numbers. The Comparator interface allows us to do the same but in a more flexible way.

What does Collections sort return in Java?

How Does Collections Sort Work in Java? The sort method transfers control to the compare method, and compare method returns values based on the arguments passed: If both the objects are equal, returns 0. If the first object is greater than the second, returns a value > 0.


1 Answers

The internal sort algorithm was changed to Tim Sort for objects and a dual-pivot quicksort for primitives as from JDK 7.

As your comparator was wrong (it was returning 0 for non-equal values), you were very lucky that it didn't break before. Now it breaks as expected.

like image 176
fps Avatar answered Oct 02 '22 02:10

fps