3

I was looking around for a method to sort a list of objects based on just one of its multiple fields (and i ended up just asking the question myself) but in my research, I came across this answer:

https://stackoverflow.com/a/1421537/1549672

I'm fairly new to java and this may be why, but I don't quite understand this last method:

public static Comparator<Person> getComparator(final PersonComparator... multipleOptions) {
    return new Comparator<Person>() {
        public int compare(Person o1, Person o2) {
            for (PersonComparator option : multipleOptions) {
                int result = option.compare(o1, o2);
                if (result != 0) {
                    return result;
                }
            }
            return 0;
        }
    };
}

could someone please explain how it works...and what exactly it does? Thanks!

Community
  • 1
  • 1
user1549672
  • 486
  • 1
  • 6
  • 16
  • 1
    I would step through the code in your debugger. This would allow you to see what each line does. – Peter Lawrey Aug 02 '12 at 21:31
  • In this case it might actually be a bit difficult since the code execution is relatively complex. and the "compare" might not even get executed unless you write your own code to execute it. – Markus Mikkolainen Aug 02 '12 at 21:37
  • Take a look at http://docs.oracle.com/javase/6/docs/api/java/lang/Enum.html#ordinal() I think this is what you are looking for. – SHiRKiT Aug 02 '12 at 21:43
  • Is there some specific part about this code that you don't understand? – Code-Apprentice Aug 02 '12 at 21:52

5 Answers5

4

It will find the first comparator that will not return "equals" and return its value, otherwise it will return "equals".

Actually it will create a new Comparator to do this, by creating an anonymous class based on the Comparator-interface.

public static Comparator<Person> getComparator(
   final PersonComparator... multipleOptions) 
{        
    return new Comparator<Person>() { //create anonymous class 
        public int compare(Person o1, Person o2) { //which implements the only method 
                                                   //in Comparator
            for (PersonComparator option : multipleOptions) { //loop through given 
                                                              //comparators
                int result = option.compare(o1, o2);
                if (result != 0) {                         //return value of the first
                    return result;                         //which says "non-equal"
                }
            }
            return 0;//all said "equals" so we say "equals"
        }
    };
}
Markus Mikkolainen
  • 3,397
  • 18
  • 21
1

You are comparing two person objects using Comparator.

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

kosa
  • 65,990
  • 13
  • 130
  • 167
1

getComparator method will return comparator that will compare two Person objects based on comparators passed in its arguments. Each of PersonComparators is designed to compare Person by one of Person class field, for example

  • PersonComparator.ID_SORT will compare Person objects by id (0 < 1 < 2 < 3 < ...)
  • PersonComparator.NAME_SORT will compare Person objects by name using natural (dictionary) order ("a" < "aa" < "ab" < "b").

If your Person class have more fields then you can add new comparator to enum PersonComparator.

Also order of PersonComparators passed to getComparator method is important.
For example, if you have Persons

Person p1 = new Person(1,"Jack");
Person p2 = new Person(2,"Jack");
Person p3 = new Person(2,"Adam");

and you will create comparator by

getComparator(PersonComparator.ID_SORT,PersonComparator.NAME_SORT) 

it will sort person first by their ids and in case ids ware equal then it will sort them by their name

(1,"Jack") (2,"Adam") (2,"Jack")

Also comparator created by

getComparator(PersonComparator.NAME_SORT, PersonComparator.ID_SORT) 

will firs compare names and only if names are equal it will compare ids of Persons, so you will get persons sorted this way

(2,"Adam") (1,"Jack") (2,"Jack")

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • Thank you! this was actually exactly what I was looking for! Just to clarify though, when you run getComparator, is it possible to use only 1 field? (ex. getComparator(PersonComparator.NAME_SORT) )? – user1549672 Aug 02 '12 at 22:41
  • 1
    Glad I could help. Also wanted to describe code but Markus Mikkolainen did it very good in his answer :) – Pshemo Aug 02 '12 at 22:43
0

Basically this method receives a variable number of PersonComparator objects and then iterates through them to compare two person objects returning the first comparator that does not return a match between two given person objects.

ricardoespsanto
  • 1,000
  • 10
  • 34
0

You pass list of other comparators final PersonComparator... multipleOptions to method getComparator.

Your comparator use this PersonComparators in for loop and returns result if persons not equal due to current PersonComparator.

So, basically, this method returns Comparator, that return 0 if Persons are equal due to all passed comparators or return first non-matching int from the passed comparator compareTo method.

mishadoff
  • 10,719
  • 2
  • 33
  • 55