How to rewrite the valuemapper function using java lambda

Is it possible / correct (to) or rewrite the following with lambda? Here, I provide an inline implementation for the keymapper and valuemapper functions

public Map<Integer,List<Employee>> getSubordinateHighestSalEmpMapV1(List<Employee> employees) {

        return employees.stream()
        .filter(e -> e.getSubordinates() != null)
        .collect(Collectors.toMap( //keyMapper
         new Function<Employee,Integer>() {

            @Override
            public Integer apply(Employee t) {
                return t.getId();
            }
        },new Function<Employee,List<Employee>>() {//valueMapper

            @Override
            public List<Employee> apply(Employee t) {
                List<Employee> subordinates = t.getSubordinates();
                List<Employee> subOrdinatesListWithHighestSalary = new ArrayList<>();
                int maxSal = Integer.MIN_VALUE;
                for(Employee s: subordinates) {
                    if(s.getSalary() >= maxSal) {
                        maxSal = s.getSalary();
                    }
                }
                for(Employee s: subordinates) {
                    if(s.getSalary() == maxSal) {
                        subOrdinatesListWithHighestSalary.add(s);
                    }
                }
                return subOrdinatesListWithHighestSalary;
            }
        }));
    }

What do I want to achieve:

Employee class has list < employee > subordinates I want to get the highest salary among the subordinates of every employee Every employee may or may not have subordinates If the subordinate is not present, it is not included in the result If more than one subordinate has the same highest salary, all subordinates should appear in the results

For example, it is similar to getting the highest paid employee in each department (employee, if salary matches)

Employee. java

import java.util.List;

public class Employee{

    private int id;
    private int salary;
    private List<Employee> subordinates;
    private String name;
    private int age;

    public int getId() {
        return id;
    }
    public Employee setId(int id) {
        this.id = id;
        return this;
    }
    public int getSalary() {
        return salary;
    }
    public Employee setSalary(int salary) {
        this.salary = salary;
        return this;
    }
    public List<Employee> getSubordinates() {
        return subordinates;

    }
    public Employee setSubordinates(List<Employee> subordinates) {
        this.subordinates = subordinates;
        return this;
    }
    public String getName() {
        return name;
    }
    public Employee setName(String name) {
        this.name = name;
        return this;
    }
    public int getAge() {
        return age;
    }
    public Employee setAge(int age) {
        this.age = age;
        return this;
    }
    @Override
    public String toString() {
        return "Employee [id=" + id + ",salary=" + salary  + ",name=" + name
                + ",age=" + age + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (id != other.id)
            return false;
        return true;
    }
}

For example, for the following inputs:

>Employee1 (ID: 100) has employee2, employee3, employee4, etc. employee3 pays up to 30000, which should be part of the output > employee2 (ID: 101) has employee5 and employee6, in which the maximum salary of employee5 is 20000, which should be part of the output > employee3 (ID: 102) has employee7 and employee8, both of which have 16000 salaries, and the output should include both. > Employee8 (ID: 107) has a subordinate employee9 with a salary of 12000. Employee9 should be part of the output

Enter as follows:

private static List<Employee>  getEmployeeListV1() {
    int i = 100;
    Employee employee1 = (Employee) new Employee().setId(i++).setSalary(10000).setAge(101).setName("emp 1");
    Employee employee2 = (Employee) new Employee().setId(i++).setSalary(20000).setAge(110).setName("emp 2");
    Employee employee3 = (Employee) new Employee().setId(i++).setSalary(30000).setAge(20).setName("emp 3");
    Employee employee4 = (Employee) new Employee().setId(i++).setSalary(10000).setAge(32).setName("emp 4");
    Employee employee5 = (Employee) new Employee().setId(i++).setSalary(20000).setAge(34).setName("emp 5");
    Employee employee6 = (Employee) new Employee().setId(i++).setSalary(15000).setAge(44).setName("emp 6");
    Employee employee7 = (Employee) new Employee().setId(i++).setSalary(16000).setAge(56).setName("emp 7");
    Employee employee8 = (Employee) new Employee().setId(i++).setSalary(16000).setAge(65).setName("emp 8");
    Employee employee9 = (Employee) new Employee().setId(i++).setSalary(12000).setAge(74).setName("emp 9");

    employee1.setSubordinates(Stream.of(employee2,employee4).collect(Collectors.toList()));
    employee2.setSubordinates(Stream.of(employee5,employee6).collect(Collectors.toList()));
    employee3.setSubordinates(Stream.of(employee7,employee8).collect(Collectors.toList()));
    employee8.setSubordinates(Stream.of(employee9).collect(Collectors.toList()));

    List<Employee> employees = Stream.of(employee1,employee2,employee4,employee5,employee7,employee8,employee9).collect(Collectors.toList());
    return employees;

}

The following is the output:

100=[Employee [id=102,salary=30000,name=emp 3,age=20]]
101=[Employee [id=104,salary=20000,name=emp 5,age=34]]
102=[Employee [id=106,salary=16000,name=emp 7,age=56],Employee [id=107,name=emp 8,age=65]]
107=[Employee [id=108,salary=12000,name=emp 9,age=74]]

Interpretation:

Solution

Of course, you can change keymapper to lambda using method references (Employee:: getid or lambda employee – > employee. Getid()) and valuemapper (t – > {...), as follows:

return employees.stream()
                .filter(e -> e.getSubordinates() != null)
                .collect(Collectors.toMap( //keyMapper
                        Employee::getId,t -> {
                            List<Employee> subordinates = t.getSubordinates();
                            List<Employee> subOrdinatesListWithHighestSalary = new ArrayList<>();
                            int maxSal = Integer.MIN_VALUE;
                            for(Employee s: subordinates) {
                                if(s.getSalary() >= maxSal) {
                                    maxSal = s.getSalary();
                                }
                            }
                            for(Employee s: subordinates) {
                                if(s.getSalary() == maxSal) {
                                    subOrdinatesListWithHighestSalary.add(s);
                                }
                            }
                            return subOrdinatesListWithHighestSalary;
                        }));

You can further simplify the method:

return employees.stream()
         .filter(e -> e.getSubordinates() != null)
         .collect(Collectors.toMap(Employee::getId,t -> {
                            int maxSal = t.getSubordinates().stream().mapToInt(Employee::getSalary).max().orElse(Integer.MIN_VALUE);
                            return t.getSubordinates().stream().filter(x -> x.getSalary() == maxSal).collect(toCollection(ArrayList::new));

                        }));

Even further:

return employees.stream()
                .filter(e -> e.getSubordinates() != null)
                .collect(Collectors.toMap(Employee::getId,Main::apply));

Since you have this method:

static List<Employee> apply(Employee t) {
        List<Employee> subordinates = t.getSubordinates();
        int maxSal = subordinates.stream().mapToInt(Employee::getSalary).max().orElse(Integer.MIN_VALUE);
        return subordinates.stream().filter(x -> x.getSalary() == maxSal).collect(toCollection(ArrayList::new));
}

Main refers to the class containing the apply helper method

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>