Search code examples
javacomparator

How to combine multiple Comparator?


My very first post question here, be gentle please :)

I am trying to create a comparator in Java that sorts based on various criteria. The Main class is very basic, it has several variables which the sorting is based on.

For example, a "Book" class, which has :

  • page number,
  • title,
  • average wordcount per page.

Here is what "intructions" i was given:

Write a ComplexComperator, which can sort based on multiple variables. Make 2 constructors:

One with 2 parameters

 public ComplexComparator(Comparator<Book> x, Comparator<Book> y)

If both items are equal based on first parameter, then it sorts based on the second parameter,

And another with 4 parameters

 public ComplexComparator(Comparator<Book> x, boolean h, Comparator<Book> y, boolean i)

If the logical variables are true, it sorts it in a natural order based on that Comparator - so it works the same as the 2-parameter constructor. If one of the logical variables takes a false value, it will reverse the natural order.

So, thats it. I wrote simple Comparators but i don't know how to handle this one. I don't know what the compare method should look like; or even if I have to add some kind of class variable... Thank you for any help!


Solution

  • 1. How to do

    You may add a Comparator<Book> in your ComplexComparator class and you just need to check the different possibilities for the conditions in you constructor :

    public class ComplexComparator implements Comparator<Book>{
    
        private Comparator<Book> comp;
    
        public ComplexComparator(Comparator<Book> x, Comparator<Book> y) {
            comp = x.thenComparing(y);
        }
    
        public ComplexComparator(Comparator<Book> x, boolean h, Comparator<Book> y, boolean i) {
            if (h && i) {
                comp = x.thenComparing(y);
            } else if (h) {
                comp = x.thenComparing(y.reversed());
            } else if (i) {
                comp = x.reversed().thenComparing(y);
            } else {
                comp = x.reversed().thenComparing(y.reversed());
            }
        }
    
        @Override
        public int compare(Book o1, Book o2) {
            return comp.compare(o1, o2);
        }
    }
    

    2. How to create it

    If you have the correct getters you can use as

    public static void main(String[] args) {
        Comparator<Book> page = Comparator.comparing(Book::getPageNb);
        Comparator<Book> title = Comparator.comparing(Book::getTitle);
    
        ComplexComparator c1 = new ComplexComparator(page, title);
        ComplexComparator c2 = new ComplexComparator(page, true, title, false);
    }
    

    3. How to use it

    Full Workable Demo