Showing posts with label Comparator. Show all posts
Showing posts with label Comparator. Show all posts

Tuesday, July 9, 2019

Sort Employees by Name and Age Using Java 8

This program for writing a program to sort the employee by name and age using JDK 8. Java 8 introduced many out of box features for developers. The comparator in java 8 is marked as @FunctionalInterface, and it provide a cleaner way to develop your code. We had already discussed how the Comparator<T> interface works before java 8. In this post, we will use the stream API with comparator. 


Employee.java


package com.techbyteslearn.lab.basic;

public class Employee {
private String name;
private int age;
private String department;
public Employee(String name, int age, String department) {
super();
this.name = name;
this.age = age;
this.department = department;
}
@Override
public String toString() {
return "\n Employee [name=" + name + ", age=" + age + ", department=" + department + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}


Now we will create an action or main method to use the above POJO class for sorting.

SortEmployeeWithStream.java

package com.techbyteslearn.lab.basic;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Collectors;
public class SortEmployeeWithStream {
public static void main(String[] args) {
Employee1 e1 = new Employee1("Ander Koli", 32, "Sales");
Employee1 e2 = new Employee1("Andrew Smith", 23, "Sales");
Employee1 e3 = new Employee1("David Jone", 52, "Sales");
Employee1 e4 = new Employee1("Cuba Station", 23, "Marketing");
Employee1 e5 = new Employee1("Bradley Head", 23, "Marketing");
Employee1 e6 = new Employee1("Peter Parker", 34, "Sales");
// Create an arraylist and add all the employee object into that list.
ArrayList<Employee1> employeeList = new ArrayList<Employee1>();
employeeList.add(e1);
employeeList.add(e2);
employeeList.add(e3);
employeeList.add(e4);
employeeList.add(e5);
employeeList.add(e6);
System.out.println("Employee list before sorting -\n" + employeeList);
ArrayList<Employee1> sortedList = (ArrayList) employeeList.stream()
.sorted(Comparator.comparing(Employee1::getName).thenComparing(Employee1::getAge))
.collect(Collectors.toList());
System.out.println("Employee list after sorting -\n" + sortedList);
}
}


Output-

Employee list before sorting -
[
 Employee1 [name=Ander Koli, age=32, department=Sales],
 Employee1 [name=Andrew Smith, age=23, department=Sales],
 Employee1 [name=David Jone, age=52, department=Sales],
 Employee1 [name=Cuba Station, age=23, department=Marketing],
 Employee1 [name=Bradley Head, age=23, department=Marketing],
 Employee1 [name=Peter Parker, age=34, department=Sales]]
Employee list after sorting -
[
 Employee1 [name=Ander Koli, age=32, department=Sales],
 Employee1 [name=Andrew Smith, age=23, department=Sales],
 Employee1 [name=Bradley Head, age=23, department=Marketing],
 Employee1 [name=Cuba Station, age=23, department=Marketing],
 Employee1 [name=David Jone, age=52, department=Sales],
 Employee1 [name=Peter Parker, age=34, department=Sales]]

The Comparator.comparing  and thenComparing  two static methods inside Comparator. As we know Comparator is a Functional interface which provides default and static methods along with implementation.  These functional interfaces are giving out of box functionality. See how before java 8 with Comparator interface examples.

Also we can achieve the above sorting by creating multiple different comparators , which we can use when we need. 

We have created two comparator as compareByAge, CompareByDept . Now we can use those comparators at any place we need along with stream. Below sample code snippet shows the usages. Read these reference documents for more about  stream, comparator, functions, jdk 8 features.


Comparator<Employee1> compareByAge = Comparator.comparing(Employee1::getAge);
Comparator<Employee1> compareByDept = Comparator.comparing(Employee1::getDepartment);
ArrayList<Employee1> sortedList = (ArrayList) employeeList.stream()
.sorted(compareByAge.thenComparing(compareByDept)).collect(Collectors.toList());


Comparable vs Comparator in Java: Understanding the Comparable Interface


In this article we will see what is Comparable<T> interface ? How to use this interface with some sample examples ?

The Comparator interface is present inside java.util package. Its comparison function, which imposes a total ordering on some collection of objects. Its mostly used while sorting a collection of objects.  Means, it compares its two arguments for order.  Returns a negative integer,zero, or a positive integer as the first argument is less than, equal to, or greater than the second one.

The Comparators can be passed to a sort method (i.e. Collections.sort or Arrays.sort) to allow precise control over the sorting order. Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don't have a natural ordering.

This interface has one important method (Before JDK 8)  -

int compare(T o1, T o2);



The below Employee class is our POJO , we will use this class to sort the employee list by age and department.

Employee.java

package com.techbyteslearn.lab.basic;

public class Employee {
private String name;
private int age;
private String department;
public Employee(String name, int age, String department) {
super();
this.name = name;
this.age = age;
this.department = department;
}
@Override
public String toString() {
return "\n Employee [name=" + name + ", age=" + age + ", department=" + department + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}

Now, we need to create a comparator to compare two same objects. We can create as many comparators by implementing each field/attributes of the pojo. Its purely business requirement, how you need your sorting functionality. Here we need the sorting based on the employee  age and employee department.

EmployeeAgeComparator.java

package com.techbyteslearn.lab.basic;
import java.util.Comparator;

public class EmployeeAgeComparator implements Comparator<Employee> {
@Override
public int compare(Employee emp1, Employee emp2) {
return emp1.getAge() - emp2.getAge();
}
}


EmployeeDeptComparator.java

package com.techbyteslearn.lab.basic;
import java.util.Comparator;

public class EmployeeDeptComparator implements Comparator<Employee> {
@Override
public int compare(Employee emp1, Employee emp2) {
// Internally for comparing String we need to use compareTo()
return emp1.getDepartment().compareTo(emp2.getDepartment());
}
}

In the above we created two comparator for age and department. Now, we need to action on our comparators. We will call our newly created comparator from main() and see the result. Below EmployeeComparatorExample class show the comparator in action.


EmployeeComparatorExample.java

package com.techbyteslearn.lab.basic;
import java.util.ArrayList;
import java.util.Collections;

public class EmployeeComparatorExample {
public static void main(String[] args) {
Employee e1 = new Employee("Matt Kuban", 32, "IT");
Employee e2 = new Employee("Andrew Smith", 42, "HR");
Employee e3 = new Employee("Butler Jason", 52, "HR");
Employee e4 = new Employee("Miss Linda", 35, "HR");
Employee e5 = new Employee("Bradley Head", 23, "IT");
Employee e6 = new Employee("Peter Parker", 34, "ADMIN");
// Create an arraylist and add all the employee object into that list.
ArrayList<Employee> employeeList = new ArrayList<Employee>();
employeeList.add(e1);
employeeList.add(e2);
employeeList.add(e3);
employeeList.add(e4);
employeeList.add(e5);
employeeList.add(e6);
System.out.println("Employee Before Sort ::" + employeeList);
// Using EmployeeAgeComparator - to sort the employee by Age
EmployeeAgeComparator ageComparator = new EmployeeAgeComparator();
Collections.sort(employeeList, ageComparator);
// Using EmployeeDeptComparator - to sort the employee by Department
EmployeeDeptComparator deptComparator = new EmployeeDeptComparator();
Collections.sort(employeeList, deptComparator);
System.out.println("Employee After Sort ::" + employeeList);
}
}

Output :- 

Employee Before Sort ::[
 Employee [name=Matt Kuban, age=32, department=IT],
 Employee [name=Andrew Smith, age=42, department=HR],
 Employee [name=Butler Jason, age=52, department=HR],
 Employee [name=Miss Linda, age=35, department=HR],
 Employee [name=Bradley Head, age=23, department=IT],
 Employee [name=Peter Parker, age=34, department=ADMIN]]

Employee After Sort ::[
 Employee [name=Peter Parker, age=34, department=ADMIN],
 Employee [name=Miss Linda, age=35, department=HR],
 Employee [name=Andrew Smith, age=42, department=HR],
 Employee [name=Butler Jason, age=52, department=HR],
 Employee [name=Bradley Head, age=23, department=IT],
 Employee [name=Matt Kuban, age=32, department=IT]]


JAVA 8 

In JDK 8,  Comparator<T> is functional Interface. Its annotated with @FunctionalInterface and this comparator interface has added few more default & static methods. As its a functional interface therefore its will be used as the assignment target for a lambda expression or method reference.

Below are few examples :-

default Comparator<T> reversed()
default Comparator<T> thenComparing(Comparator<? super T> other)
default <U> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor,
            Comparator<? super U> keyComparator)
default <U extends Comparable<? super U>> Comparator<T> thenComparing(
            Function<? super T, ? extends U> keyExtractor)
default Comparator<T> thenComparingInt(ToIntFunction<? super T> keyExtractor)



Here is the full list of methods added into Comparator<T> . We can use stream api of java 8 with lambda expression to implements comparator interface. We will see in the next subsequent posts on lambda expression and stream api.



Happy Learning.