Pages

Java: Comparator class for different ways of sorting custom objects' collection

Suppose you have a simple class called Book which has attributes title, author, and price. You may need to sort them according to each attribute and both in ascending and descending order. Now you may implement your own method, but the really simple and efficient way is to use the inbuilt Comparator Interface. This is the in-built generic interface in java which you can implement on any object. Just override its compare method and write the logic to return the -1, 0 and 1.

Example.

package odesk;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 *
 * @author Rajan Prasad Upadhyay
 * works fine
 */
public class Book {
    private String title;
    private String author;
    private double price;

    public Book(String title, String author, double price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public double getPrice() {
        return price;
    }

    public String toString() {
        return title + ": " + author + ": " + price;
    }
    
    public boolean equals(Book book2){
        return author.equals(book2.getAuthor());
    }

    public static void main(String[] args) {
        List<Book> booksList = new ArrayList<Book>();
        booksList.add(new Book("Book1", "Rajan", 100));
        booksList.add(new Book("Book2", "Dummy2", 10));
        booksList.add(new Book("Book3", "Dummy", 17));
        booksList.add(new Book("Book4", "Rajan2", 90));
        System.out.println(booksList);
        
        Bookstore bs = new Bookstore(booksList);
        
        int order = 1;
        System.out.println( bs.getBooksSortedByPrice(order));
        
        System.out.println(bs.getBooksByAuthor("Rajan"));
    }
}

//<editor-fold defaultstate="collapsed" desc="comparators">
class PriceComparatorASC implements Comparator<Book> {

    @Override
    public int compare(Book t, Book t1) {
        if (t.getPrice() < t1.getPrice()) {
            return -1;
        } else if (t.getPrice() == t1.getPrice()) {
            return 0;
        } else {
            return 1;
        }
    }
}

class TitleComparatorASC implements Comparator<Book> {

    @Override
    public int compare(Book t, Book t1) {
        return t.getTitle().compareTo(t1.getTitle());
    }
}

class AuthorComparatorASC implements Comparator<Book> {

    @Override
    public int compare(Book t, Book t1) {
        return t.getAuthor().compareTo(t1.getAuthor());
    }
}

class PriceComparatorDESC implements Comparator<Book> {

    @Override
    public int compare(Book t1, Book t) {
        if (t.getPrice() < t1.getPrice()) {
            return -1;
        } else if (t.getPrice() == t1.getPrice()) {
            return 0;
        } else {
            return 1;
        }
    }
}

class TitleComparatorDESC implements Comparator<Book> {

    @Override
    public int compare(Book t1, Book t) {
        return t.getTitle().compareTo(t1.getTitle());
    }
}

class AuthorComparatorDESC implements Comparator<Book> {

    @Override
    public int compare(Book t1, Book t) {
        return t.getAuthor().compareTo(t1.getAuthor());
    }
}
//</editor-fold>

class Bookstore {

    List<Book> books = new ArrayList<Book>();

    public Bookstore(List<Book> books) {
        this.books = books;
    }

    public List<Book> getBooksSortedByPrice(int order) {
        // implement this method:
        // if order is 0, return the list of books sorted by price in ascending order,
        // if order is 1, return the list of books sorted by price in descending order
        //Collections.sort(books);
        if (order == 0) {
            Collections.sort(books, new PriceComparatorASC());
        } else if (order == 1) {
            Collections.sort(books, new PriceComparatorDESC());
        }
        return books;
    }

    public List<Book> getBooksSortedByTitle(int order) {
        // implement this method:
        // if order is 0, return the list of books sorted by title in ascending order,
        // if order is 1, return the list of books sorted by title in descending order
        if (order == 0) {
            Collections.sort(books, new TitleComparatorASC());
        } else if (order == 1) {
            Collections.sort(books, new TitleComparatorDESC());
        }
        return books;
    }

    public List<Book> getBooksByAuthor(String author) {
        // this method returns the list of books for a given author
        // do not make any changes to this method
        // change the Book class to make sure this method will work correctly
        List<Book> result = new ArrayList<Book>();
        Book helperBook = new Book("Dummy", author, 0.0);
        for (Book b : books) {
            if (b.equals(helperBook)) {
                result.add(b);
            }
        }
        return result;
    }
}