1

I have an object with following properties:

MyObject {

int order;
Date date;

}

I have a list of objects:

[
  {1, 2010},
  {9, 2011},
  {9, 2020},
  {2, 2001},
  {1, 2001}
]

I want to first sort on order (ascending) and than Date (descending), so expected output:

[
  {1, 2010},
  {1, 2001}
  {2, 2001}
  {9, 2011},
  {9, 2020},
]

I found following code How do I sort a list by different parameters at different timed

enum PersonComparator implements Comparator<Person> {
    ID_SORT {
        public int compare(Person o1, Person o2) {
            return Integer.valueOf(o1.getId()).compareTo(o2.getId());
        }},
    NAME_SORT {
        public int compare(Person o1, Person o2) {
            return o1.getFullName().compareTo(o2.getFullName());
        }};

    public static Comparator<Person> decending(final Comparator<Person> other) {
        return new Comparator<Person>() {
            public int compare(Person o1, Person o2) {
                return -1 * other.compare(o1, o2);
            }
        };
    }

    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;
            }
        };
    }
}

My confusion/question is :

            public int compare(Person o1, Person o2) {
                for (PersonComparator option : multipleOptions) {
                    int result = option.compare(o1, o2);
                    if (result != 0) {
                        return result;
                    }
                }
                return 0;
            }

It says if (result != 0) then return result

which means if I call like Collections.sort(list, decending(getComparator(NAME_SORT, ID_SORT)));

and "name" compare returns non-zero, it will not apply compare to "ID_SORT"

How would it work?? Please explain how will the code above will work for my example above?

Or am I completely missing the point?

Community
  • 1
  • 1
GJain
  • 5,025
  • 6
  • 48
  • 82
  • 1
    Yes, that's how it will work. By the way, if an object is *lower than* other by the name, why should they be compared against the ID? – Luiggi Mendoza Aug 08 '14 at 17:34

2 Answers2

1

The above code looks like it has an order of sorting criteria.

"name" compare returns non-zero, it will not apply compare to "ID_SORT"

This is the right behavior; if it is zero, they are equal so move on to the next criteria. Otherwise use this one.

However, I can suggest another method - use the fact that the library sorts are stable, and so if you apply sort first by year, then by order, you get the list sorted by order and if the order is the same, then by date.

nair.ashvin
  • 791
  • 3
  • 11
1

It says if (result != 0) then return result which means if I call like Collections.sort(list, decending(getComparator(NAME_SORT, ID_SORT))); and "name" compare returns non-zero, it will not apply compare to "ID_SORT"

When "NAME_SORT" comparator returns non-zero at this line:- int result = option.compare(o1, o2);

Then the custom comparator created in your getComparator method will rearrange (sort) o1 and o2 according to the compare logic in NAME_SORT's compare method.

Now in case if NAME_SORT comparator finds that the two objects in comparison are same then without returing anything the custom comparator created in the getcomparator checks for the next comparator's compare method till it finishes all the passed comparators.

For your case you need to compare the ids and then go for the date comparator in the same way.

Manjunath
  • 1,685
  • 9
  • 9