-1

I am new with Stream API, Lambdas and Enums, How can I use enums to sort my list BYNAME, BYSALARY?

import java.util.*; import java.util.function.*; import java.util.stream.Stream; class Employee { String name; int salary; Employee(String name,int salary) { this.name = name; this.salary = salary; } public String getName() { return this.name; } public int getSalary() { return this.salary; } public void setName(String name) { this.name = name; } public void setSalary(int salary) { this.salary = salary; } } class EmployeeInfo { enum SortMethod { BYNAME,BYSALARY; //Do I have to do something here? }; public List<Employee> sort(List<Employee> emps,final SortMethod method) { //What I have to Write here? } } 

I have to define sort method to return my list by using enum.

1
  • You need to write some code there and give it a try! Commented Mar 11, 2020 at 15:55

3 Answers 3

3

Here is one option. You can have the Enum implement the Comparator interface for type Employee then delegate the Comparator to each element by having a constructor that provides a Comparator. You can then have the sort function use Stream#sorted and the enum object since it implements Comparator to handle the sorting and return a new list without modifying the old one.

 enum SortMethod implements Comparator<Employee> { NAME(Comparator.comparing(Employee::getName)), SALARY(Comparator.comparingInt(Employee::getSalary)); private final Comparator<Employee> comparator; SortMethod(Comparator<Employee> comparator) { this.comparator = comparator; } @Override public int compare(Employee o1, Employee o2) { return comparator.compare(o1, o2); } }; public List<Employee> sort(List<Employee> emps,final SortMethod method){ return emps.stream().sorted(method).collect(Collectors.toList()); } 

On an unrelated note

Try to make Employee immutable. Always make objects immutable unless you otherwise need to. If you need to change the state of an Object just return a new object by using the old one.

Employee employeeWithRaise = underpaidEmployee.increaseSalary(10_000); 

Employee#increaseSalaray might look like this;

public Employee increaseSalary(int salaryIncrease) { return new Employee(name, salary + salaryIncrease); } 
Sign up to request clarification or add additional context in comments.

4 Comments

private final Comparator<Employee> comparator; what is this? is it variable or object of comparator type?
That is a member of SortMethod, specifically a class method. It is a Comparator object of type Employee.
so we are passing "Name" as argument in sort method and it is initializing comparator in SortMethod and then going to compare(Emp 1,Emp2) and then comparing using Name(Comparator.comparing(Employee::getName))?
Well Comparator is just an interface that implements a single method compare(T, T) which abides by the Comparable contract. Comparator.comparing accepts a Function of type T (Employee) so that it can compare both objects based off a single function, in this case getName() which returns a String, from Employee.
1

This might be a duplicate to Sorting a list with stream.sorted() in Java I don't see why you want to use an enum to see how you want to sort.

I would make 2 diffrent methods to sort and call those methods when you want to use them

emps.stream() .sort((emp1, emp2)->emp1.getName().compareTo(emp2.getName())); 

and one where you change getName() by getSalary()

Comments

1

You can create two Comparator classes, one for comparing salary and another one for comparing names. Then you can call the sort(Comparator) method on the list to sort it using that comparator.

Example:

import java.util.ArrayList; import java.util.Comparator; import java.util.List; class Main { public static void main(String[] args) { List<Employee> employeeList = new ArrayList<>(); employeeList.add(new Employee("b", 5)); employeeList.add(new Employee("a", 10)); employeeList.add(new Employee("c", 1)); employeeList.sort(new NameComparator()); System.out.println("by name:"); employeeList.forEach(System.out::println); employeeList.sort(new SalaryComparator()); System.out.println("by salary:"); employeeList.forEach(System.out::println); } } class Employee { String name; int salary; Employee(String name, int salary) { this.name = name; this.salary = salary; } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", salary=" + salary + '}'; } } class NameComparator implements Comparator<Employee> { @Override public int compare(Employee o1, Employee o2) { return o1.name.compareTo(o2.name); } } class SalaryComparator implements Comparator<Employee> { @Override public int compare(Employee o1, Employee o2) { return Integer.compare(o1.salary, o2.salary); } } 

This generates the following output:

 by name: Employee{name='a', salary=10} Employee{name='b', salary=5} Employee{name='c', salary=1} by salary: Employee{name='c', salary=1} Employee{name='b', salary=5} Employee{name='a', salary=10} 

Depending on the complexity of your project, you can have a static factory function to get comparators.

class EmpComparatorFactory { public static Comparator<Employee> getComparator(EmpSort sortType) { switch (sortType) { case NAME_ASC: return new EmpComparatorName(); case NAME_DSC: return new EmpComparatorName().reversed(); case SALARY_ASC: return new EmpComparatorSalary(); case SALARY_DSC: return new EmpComparatorSalary().reversed(); default: return null; } } static class EmpComparatorName implements Comparator<Employee> { @Override public int compare(Employee o1, Employee o2) { return o1.name.compareTo(o2.name); } } static class EmpComparatorSalary implements Comparator<Employee> { @Override public int compare(Employee o1, Employee o2) { return Integer.compare(o1.salary, o2.salary); } } } enum EmpSort { NAME_ASC, NAME_DSC, SALARY_ASC, SALARY_DSC } 

You can then sort the list like this employeeList.sort(EmpComparatorFactory.getComparator(EmpSort.NAME_ASC));

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.