Sorting based on multiple attributes of a Class.



In the Comparable and Comparator- part 1, 2, 3 and 4 you have seen sorting based on single attribute of a class but you may also need to sort elements based on more than one attribute.  For example if we take Book class :

public class Book{
  String title;
  String author;
  double price;
  String publisher;
  ...
}

You may need to sort books according to their authors first, then within each author books should be sorted based on their title, and within each title they should be sorted according to their price.

Lets see how to do this.

Book.java
public class Book implements Comparable<Book>{

   String title;
   String author;
   double price;
   String publisher;

     public void setTitle(String title){
       this.title=title;
     }

    public String getTitle(){
      return title;
    }

   public void setAuthor(String author){
     this.author=author;
   }

   public String getAuthor(){
    return author;
   }

   public void setPrice(double price){
    this.price=price;
   }

   public double getPrice(){
   return price;
   }

   public void setPublisher(String publisher){
    this.publisher=publisher;
  }

  public String getPublisher(){
   return publisher;
  }

public int compareTo(Book book){

     if(book == null){
       throw new NullPointerException("Book passed is null!");
    }

    if(this.getAuthor().equals(book.getAuthor())){  /*Most significant field*/
      
     if(this.getTitle().equals(book.getTitle()))   /*Next Most significant field*/
            return (int)(this.getPrice()-book.getPrice());
          else
           return this.getTitle().compareTo(book.getTitle());
     }
     else
          return this.getAuthor().compareTo(book.getAuthor());
      
  }
}

BookComparision.java
import java.util.Arrays;

public class BookComparision{
  
    public static void main(String args[]){
      
        Book book1 = new Book();       
        book1.setAuthor("Author A");
        book1.setTitle("Title B");
        book1.setPrice(225.00);
       
        Book book2 = new Book();       
        book2.setAuthor("Author A");
        book2.setTitle("Title B");
        book2.setPrice(125.00);
       
       
        Book book3 = new Book();       
        book3.setAuthor("Author B");
        book3.setTitle("Title B");
        book3.setPrice(125.00);
       
        Book book4 = new Book();       
        book4.setAuthor("Author B");
        book4.setTitle("Title A");
        book4.setPrice(200.00);
       
       
        Book book5 = new Book();       
        book5.setAuthor("Author C");
        book5.setTitle("Title C");
        book5.setPrice(125.00);
       
        Book book6 = new Book();       
        book6.setAuthor("Author C");
        book6.setTitle("Title B");
        book6.setPrice(125.00);
       
        Book book7 = new Book();       
        book7.setAuthor("Author C");
        book7.setTitle("Title B");
        book7.setPrice(400.00);
       
       /* An array containing Books*/
        Book[] bookArray = new Book[7];
        bookArray[0]=book1;
        bookArray[1]=book2;
        bookArray[2]=book3;
        bookArray[3]=book4;
        bookArray[4]=book5;
        bookArray[5]=book6;
        bookArray[6]=book7;
       
        System.out.println("Sorted Books:");
      
        Arrays.sort(bookArray);

        for(int i=0;i<=6;i++){
        System.out.print("Author:"+bookArray[i].getAuthor()+"        ");
        System.out.print("Title:"+bookArray[i].getTitle()+"        ");
        System.out.println("Price:"+bookArray[i].getPrice());

        }       
   }
 }

Output:

Sorted Books:
Author:Author A         Title:Title B           Price:125.0
Author:Author A         Title:Title B           Price:225.0
Author:Author B         Title:Title A           Price:200.0
Author:Author B         Title:Title B           Price:125.0
Author:Author C         Title:Title B           Price:125.0
Author:Author C         Title:Title B           Price:400.0
Author:Author C         Title:Title C           Price:125.0


When your comparision is based on multiple attributes, remember to on compare most significant attribute first. Which attribute is most significant it depends on you. Here we are assuming author as our most significant attribute.

When most significant attribute is equal then only go for comparing next most significant field, otherwise return the integer as shown below:


if(this.getAuthor().equals(book.getAuthor())){
       
 // check next most significant field
}
else
  return this.getAuthor().compareTo(book.getAuthor());





I would like to know your comments and if you liked the article then please share it on social networking buttons.


1 comment: