Minh Tri Le
Minh Tri Le

Reputation: 360

How to understand the order induced by the comparator in Java?

I was so confused about comparator and Collections.sort() in Java. I don't understand the order induced by the comparator. I don't clear about which number the compare function should return to get the sorting direction. I also don't know how Collections will use that compare result to sort the input data. Should I learn them by heart? Is there anything easier to understand them? Can anybody explain it for me? Thanks.

public int compare(Obj a, Obj b){ 
    if(a.age > b.age) return 1; 
    if(a.age < b.age) return -1;
    else              return 0;
}

Update

After received some explanations from some friendly Software Engineer, I understood that the comparator define the order of elements in a Collections. For example, when compare a and b, if the comparator return -1 then a should be put before b in the list.

Upvotes: 4

Views: 2544

Answers (3)

Bharatesha M
Bharatesha M

Reputation: 51

Key thing to remember is if comparison returns positive value ( >0) swap happens. Otherwise not during sorting algorithm.

Example:

4(a) 2(b) 6

For ascending order:

a > b (4 > 2) return 1 (swap requires between a and b i.e place 2 4 6)

For descending order:

a > b ( 2 > 4 ) return -1 (swap not needed between a and b i.e place 4 2 6, because it is already in order).

This logic is implemented under the sorting algorithm. So, if a and b are already in order as you expected, then return -1; otherwise, return 1.

Upvotes: 5

Naman
Naman

Reputation: 31878

Step 1

One way to simplify and correlate this could be that your code:

public int compare(Obj a, Obj b){ 
    if(a.age > b.age) return 1; 
    if(a.age < b.age) return -1;
    else              return 0;
}

would be represented as following(given age is int variable)

public int compare(Obj a, Obj b) {
    return Integer.compare(a.getAge(), b.getAge());
}

where Integer.compare internally does the same logic as you were doing previously:

return (x < y) ? -1 : ((x == y) ? 0 : 1)

Step 2

Now this can further be represented using a comparator as:

Comparator<Obj> ageComparator = Comparator.comparingInt(Obj::getAge);

which Comparator.comparingInt internally performs

return (Comparator<T> & Serializable)
        (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2));

Hence the order eventually induced by all these three forms would be same when for example you would call

objList.sort(ageComparator);

Comparable's compareTo method can elaborate more on the part of comparison

Compares this object with the specified object for order.  Returns a
negative integer, zero, or a positive integer as this object is less
than, equal to, or greater than the specified object.

and hence that is considered to be the natural ordering of the Obj when you override the compareTo extending to a Comparable<Obj>.

Upvotes: 0

Prasad Karunagoda
Prasad Karunagoda

Reputation: 2148

To sort a set of items, we should be able to compare each pair of items in that set and say which is "bigger" and which is "smaller".

Imagine you are given the task of sorting below numbers manually.

4, 2, 7, 8, 3

How would you use your mind to achieve this task? You would have to look at pairs of numbers and compare them and then figure out which is the smallest number to place at the begging.

Similarly, to achieve a sorting task, a computer needs to compare pairs of items and say which is "bigger" and which is "smaller".

So, the comparator object we write is "the definition" of which is bigger and which is smaller. When we sort numbers, this definition should say which is bigger and which is smaller. When we sort strings, this definition should say which letter in the alphabet comes first and which letter comes after.

Upvotes: 1

Related Questions