-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.

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38

3 Answers3

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);
}
Jason
  • 5,154
  • 2
  • 12
  • 22
  • private final Comparator comparator; what is this? is it variable or object of comparator type? – Ritu Raj Shrivastava Mar 11 '20 at 13:45
  • 1
    That is a member of SortMethod, specifically a class method. It is a Comparator object of type Employee. – Jason Mar 11 '20 at 13:47
  • 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))? – Ritu Raj Shrivastava Mar 11 '20 at 13:54
  • 1
    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. – Jason Mar 11 '20 at 13:57
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()

Maxime C.
  • 37
  • 11
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));

HomeIsWhereThePcIs
  • 1,273
  • 1
  • 19
  • 37