Tuesday, 4 August 2015

Comparing and Sorting list objects based on their multiple attributes

Comparing and Sorting list objects 


There are multiple ways to sort objects available in list collection based on their multiple attributes which we can treat as keys. We will see the example below where we will sort list of objects. These objects are available as pojo(plain old java objects) forms.

Employee.java

package com.gaurav.compare.lists;
/**
 * @author Gaurav
 *
 */
public class Employee {
    private String empName;
    private String designation;
    private int age;
    private int salary;

    public Employee(String name, String jobTitle, int age, int salary) {
        this.empName = name;
        this.designation = jobTitle;
        this.age = age;
        this.salary = salary;
    }

    public String toString() {
        return String.format("%s\t%s\t%d\t%d", empName, designation, age, salary); 
    }

public String getEmpName() {
return empName;
}

public void setEmpName(String empName) {
this.empName = empName;
}

public String getDesignation() {
return designation;
}

public void setDesignation(String designation) {
this.designation = designation;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public int getSalary() {
return salary;
}

public void setSalary(int salary) {
this.salary = salary;
}
}


ComparatorChain.java

package com.gaurav.compare.lists;
/**
 * @author Gaurav
 *
 */
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class ComparatorChain implements Comparator<Employee>{
private List<Comparator<Employee>> lstComparators;
 
    @SafeVarargs
public ComparatorChain(Comparator<Employee>... comparators) {
        this.lstComparators = Arrays.asList(comparators);
    }

    @Override
    public int compare(Employee employee1, Employee employee2) {
        for (Comparator<Employee> comparator : lstComparators) {
            int finalResult = comparator.compare(employee1, employee2);
            if (finalResult != 0) {
                return finalResult;
            }
        }
        return 0;
    }
}

DesignationComparator.java

package com.gaurav.compare.lists;
/**
 * @author Gaurav
 *
 */
import java.util.Comparator;

public class DesignationComparator implements Comparator<Employee>{
 @Override
   public int compare(Employee employee1, Employee employee2) {
       return employee1.getDesignation().compareTo(employee2.getDesignation());
   }
}

AgeComparator.java

package com.gaurav.compare.lists;
/**
 * @author Gaurav
 *
 */
import java.util.Comparator;

public class AgeComparator implements Comparator<Employee>{
 @Override
   public int compare(Employee employee1, Employee employee2) {
       return employee1.getAge() - employee2.getAge();
   }
}

SalaryComparator.java

package com.gaurav.compare.lists;
/**
 * @author Gaurav
 *
 */
import java.util.Comparator;

public class SalaryComparator implements Comparator<Employee>{
@Override
    public int compare(Employee employee1, Employee employee2) {
        return employee1.getSalary() - employee2.getSalary();
    }
}

ListObjectsComparisonAndSortingExample.java

package com.gaurav.compare.lists;
/**
 * @author Gaurav
 *
 */
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ListObjectsComparisonAndSortingExample {
public static void main(String[] args) {
 
       System.out.println("# COMPARING AND SORTING LIST OBJECTS BASED ON MULTIPLE ATTRIBUTES #\n");
 
       List<Employee> employeesList = new ArrayList<Employee>();
 
       employeesList.add(new Employee("Tusaar", "Developer", 44, 82000));
       employeesList.add(new Employee("Suresh", "Designer", 32, 77500));
       employeesList.add(new Employee("Bimlesh", "Designer", 44, 141900));
       employeesList.add(new Employee("Piyush", "Programmer", 26, 65700));
       employeesList.add(new Employee("Tiya", "Designer", 44, 131300));
       employeesList.add(new Employee("Culinan", "Programmer", 31, 55000));
       employeesList.add(new Employee("Amit", "Programmer", 27, 58000));
       employeesList.add(new Employee("Aaditya", "Designer", 31, 155000));
       employeesList.add(new Employee("Bimal", "Programmer", 24, 39000));
       employeesList.add(new Employee("Smith", "Developer", 29, 89000));
       employeesList.add(new Employee("Jimmy", "Developer", 36, 69000));
       employeesList.add(new Employee("Peter", "Developer", 38, 152000));
       employeesList.add(new Employee("Ali", "Programmer", 37, 85000));
       employeesList.add(new Employee("Dravid", "Developer", 33, 10000));
       employeesList.add(new Employee("Jatin", "Designer", 34, 83250));
 
       System.out.println("*** Displaying the employee list objects before sorting:\n");
 
       for (Employee employee : employeesList) {
           System.out.println(employee);
       }
 
       Collections.sort(employeesList, new ComparatorChain(
               new DesignationComparator(),
               new AgeComparator(),
               new SalaryComparator())
       );
 
       System.out.println("\n*** Displaying the employee list objects after sorting:\n");
 
       for (Employee employee : employeesList) {
           System.out.println(employee);
       }
 
   }
}


Result:-

# COMPARING AND SORTING LIST OBJECTS BASED ON MULTIPLE ATTRIBUTES #

*** Displaying the employee list objects before sorting:

Tusaar Developer 44 82000
Suresh Designer 32 77500
Bimlesh Designer 44 141900
Piyush Programmer 26 65700
Tiya Designer 44 131300
Culinan Programmer 31 55000
Amit Programmer 27 58000
Aaditya Designer 31 155000
Bimal Programmer 24 39000
Smith Developer 29 89000
Jimmy Developer 36 69000
Peter Developer 38 152000
Ali Programmer 37 85000
Dravid Developer 33 10000
Jatin Designer 34 83250

*** Displaying the employee list objects after sorting:

Aaditya Designer 31 155000
Suresh Designer 32 77500
Jatin Designer 34 83250
Tiya Designer 44 131300
Bimlesh Designer 44 141900
Smith Developer 29 89000
Dravid Developer 33 10000
Jimmy Developer 36 69000
Peter Developer 38 152000
Tusaar Developer 44 82000
Bimal Programmer 24 39000
Piyush Programmer 26 65700
Amit Programmer 27 58000
Culinan Programmer 31 55000
Ali Programmer 37 85000




Monday, 3 August 2015

Visitor Design Pattern Implementation

Visitor Design Pattern


Question : - What is Visitor Design Pattern?
Answer : - This design pattern also falls under Behavioral design pattern. Using this design pattern, we can move the operational logic from the objects to another class. This pattern is providing a way of separating an algorithm from an object structure on which it operates. This visitor pattern is used to simplify operations on groupings of related objects.

As of GOF:-Allows for one or more operation to be applied to a set of objects at runtime, decoupling the operations from the object structure.

Benefits : -

Adding new operatios are easy because if the logic of operation changes, then we need to make change only in the visitor implementation rather than doing it in all the item classes.
Visitors can gather state as they visit each element in the object structure. Without a visitor, this state would have to be passed as an extra arguments to the operations that perform the traversal.

Disadvantage : -
During design period of application, we should know the return type of visit() methods otherwise
we will have to change the interface and all of its implementations.
If there are many implementations of visitor interface then extending that class is not a easy task.

For more information on Visitor design pattern please refer to the below link

In the below example, we will see the implementation of the Visitor design pattern

BodyPart.java

package com.gaurav.designpattern.visitor;
/**
 * @author Gaurav
 *
 */
public interface BodyPart {
public void accept(BodyPartVisitor bodyPartVisitor);
}


Body.java

package com.gaurav.designpattern.visitor;
/**
 * @author Gaurav
 *
 */
public class Body implements BodyPart{
private BodyPart[] bodyParts;
public Body(){
bodyParts = new BodyPart[] {new Eye(), new Heart(), new Kidney()};
}
@Override
  public void accept(BodyPartVisitor bodyPartVisitor) {
     for (int i = 0; i < bodyParts.length; i++) {
     bodyParts[i].accept(bodyPartVisitor);
     }
     bodyPartVisitor.visit(this);
  }

}

BodyPartVisitor.java

package com.gaurav.designpattern.visitor;
/**
 * @author Gaurav
 *
 */
public interface BodyPartVisitor {
public void visit(Body body);
public void visit(Eye eye);
public void visit(Heart heart);
public void visit(Kidney kidney);
}

Eye.java

package com.gaurav.designpattern.visitor;
/**
 * @author Gaurav
 *
 */
public class Eye implements BodyPart{

@Override
public void accept(BodyPartVisitor bodyPartVisitor) {
bodyPartVisitor.visit(this);
}

}


Heart.java


package com.gaurav.designpattern.visitor;
/**
 * @author Gaurav
 *
 */
public class Heart implements BodyPart{

@Override
public void accept(BodyPartVisitor bodyPartVisitor) {
bodyPartVisitor.visit(this);
}

}

Kidney.java


package com.gaurav.designpattern.visitor;
/**
 * @author Gaurav
 *
 */
public class Kidney implements BodyPart {

@Override
public void accept(BodyPartVisitor bodyPartVisitor) {
bodyPartVisitor.visit(this);
}

}

FullBodyScanner.java

package com.gaurav.designpattern.visitor;
/**
 * @author Gaurav
 *
 */
public class FullBodyScanner implements BodyPartVisitor{

@Override
public void visit(Body body) {
System.out.println("Scanning Body");
}
@Override
public void visit(Eye eye) {
System.out.println("Scanning Eye");
}

@Override
public void visit(Heart heart) {
System.out.println("Scanning Heart");
}

@Override
public void visit(Kidney kidney) {
System.out.println("Scanning Heart");
}

}

VisitorDesignPatternDemo.java

package com.gaurav.designpattern.visitor;
/**
 * @author Gaurav
 *
 */
public class VisitorDesignPatternDemo {
public static void main(String args[]) {
BodyPart body = new Body();
body.accept(new FullBodyScanner());
}
}

Result:-

Scanning Eye
Scanning Heart
Scanning Kidney
Scanning Body

JMS                                                            JSON                                                       JDBC