Как я могу отсортировать объекты Employee с помощью констант enum? - PullRequest
0 голосов
/ 11 марта 2020

Я новичок в Stream API, Lambdas и Enums. Как я могу использовать enums для сортировки моего списка 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?
    }
}

Мне нужно определить метод сортировки для возврата моего списка с помощью enum.

Ответы [ 3 ]

3 голосов
/ 11 марта 2020

Вот один из вариантов. В Enum можно реализовать интерфейс Comparator для типа Employee, а затем делегировать Comparator каждому элементу с помощью конструктора, предоставляющего Comparator. Затем вы можете использовать функцию сортировки, используя Stream # sorted и объект enum, поскольку она реализует Comparator для обработки сортировки и возврата нового списка без изменения старого.

        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());
        }

На неродственной ноте

Попробуйте сделать сотрудника неизменным. Всегда делайте объекты неизменяемыми, если в этом нет необходимости. Если вам нужно изменить состояние объекта, просто верните новый объект, используя старый.

Employee employeeWithRaise = underpaidEmployee.increaseSalary(10_000);

Employee # увеличиваетсяSalaray может выглядеть так:

public Employee increaseSalary(int salaryIncrease) {
    return new Employee(name, salary + salaryIncrease);
}
1 голос
/ 11 марта 2020

Вы можете создать два класса Comparator, один для сравнения зарплаты, а другой для сравнения имен. Затем вы можете вызвать метод sort (Comparator) в списке, чтобы отсортировать его с помощью этого компаратора.

Пример:

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);
    }
}

Это генерирует следующий вывод:

        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}

В зависимости от сложности вашего проекта, вы можете использовать фабричную функцию stati c для получения компараторов.

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
}

Затем вы можете отсортировать список следующим образом employeeList.sort(EmpComparatorFactory.getComparator(EmpSort.NAME_ASC));

1 голос
/ 11 марта 2020

Это может быть дубликатом Сортировка списка с помощью stream.sorted () в Java Я не понимаю, почему вы хотите использовать перечисление, чтобы увидеть, как вы хотите отсортировать.

Я бы сделал 2 различных метода для сортировки и вызова этих методов, когда вы хотите их использовать

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

и один, где вы меняете getName () на getSalary ()

...