Java 8 lambda 用于为每个部门选择最高薪员工

问题描述 投票:0回答:11
class Employee {
    public string department;
    public int salary;
}

List<Employee> allEmployees = ...

我需要一个列表,其中每个部门只有 1 名最高薪员工。 allEmployees 是源列表。

java lambda java-8
11个回答
17
投票

您可以使用分组收集器来做到这一点:

Map<String, Employee> topEmployees =
    allEmployees.stream()
                .collect(groupingBy(
                    e -> e.department,
                    collectingAndThen(maxBy(comparingInt(e -> e.salary)), Optional::get) 
                ));

使用静态导入

import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.maxBy;

此代码创建所有员工的

Stream
,并在
Collectors.groupingBy
的帮助下将他们按部门分组。对于分类到同一键的所有值,我们只需要保留工资最高的员工,因此我们用
Collectors.maxBy
收集它们,比较器将工资与
Comparator.comparingInt
进行比较。由于
maxBy
返回一个
Optional<Employee>
(以处理列表为空的情况),我们通过调用
Collectors.collectingAndThen
来包装它,并使用仅返回员工的完成器:我们知道在这种情况下,可选不会为空。


7
投票

替代解决方案:

Map<String, Employee> topEmployees =
    allEmployees.stream()
            .collect(Collectors.toMap(
                e -> e.department,
                e -> e,
                BinaryOperator.maxBy(Comparator.comparingInt(e -> e.salary)) 
            ));

当我们遇到部门的第一位员工时,我们会向

Map
添加一个新条目。当找到另一名员工时,工资更高的人会被保留。这样你就不需要干预选项。


3
投票

/假设您有一个员工列表,如 List employeeList; 要首先找到部门工资,您需要有员工比较器/

Comparator<Employee> bySalary = Comparator.comparing(Employee::getSalary);

然后找到您所在部门的最高薪水

Map<String, Optional<Employee>> collect = 
        employeeList.stream().collect(
            Collectors.groupingBy(
                Employee::getDept,
                Collectors.reducing(BinaryOperator.maxBy(bySalary))
    )
);

我们在这里做的是, 我们根据部门对员工进行分组。 除了分组之外,我们还说让我返回该部门最高薪水的人, 最后只选择最大一个。 要查看输出覆盖 Employee 类中的 toString 方法并执行 */

collect.entrySet().stream().forEach(System.out::println);

1
投票

老实说,这不是一个解决方案。 由于声誉较低,我无法发表评论,这只是一个微小的观察,导致了这次修正/即兴创作。

我遇到了同样的情况,我尝试了上面提到的Tagir Valeev's解决方案,这对我有用。 我在 IDE 中照样使用它,但是返回的结果是错误的,因为编译器抱怨如下:

编译时错误:无法从

Map<Object, Object>
转换为
Map<String, Employee>

这就是我理解这里预期返回类型是 Object 类类型的地方,而不是我们期望的,即

Map<String, Employee>

我只需将结果接收到

Map<Object, Object>
而不是
Map<String, Employee>

因此,下面的代码将迭代

Map<Object, Object> topEmployees
并将最终的预期结果存储到
Map<String, Employee> finalResult;

Tagir Valeev 的解决方案如下,我在接收端进行了调整:

Map<Object, Object> topEmployees = empList.stream()
            .collect(Collectors.groupingBy(e -> e.department, 
                    Collectors.collectingAndThen(
                            Collectors.maxBy(Comparator.comparingDouble(e -> e.salary)), Optional::get
                                                )
                                )
            );

我编写的额外代码如下:

for(Map.Entry<Object, Object> token : topEmployees.entrySet()) {
        finalResult.put((String) token.getKey() , (Employee) token.getValue());
    }

希望这对某人有帮助。谢谢。


0
投票

Map 结果 = li.stream().collect(Collectors.groupingBy(Emp::getDept, Collectors.reducing(BinaryOperator.maxBy(Comparator.comparing(Emp::getSalary))) ));


0
投票

每个部门的最高工资java 8


导入java.util.*;

导入java.util.stream.Collectors;

Map<String, Employee> stringEmployeeMap= employeeList.stream()
               .collect(Collectors.groupingBy(Employee::getDepartment,
                       Collectors.collectingAndThen(
                               Collectors.maxBy(
                                       Comparator.comparingDouble(Employee::getSalary)
                               ), Optional::get)
               )
               );

0
投票
import static java.util.Comparator.comparingDouble;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.maxBy;

empList.stream().collect(
            groupingBy(e -> e.department,
            collectingAndThen(maxBy(comparingDouble(e -> e.salary)), 
            Optional::get))).
            forEach((k, v) -> System.out.println(k + ":" + v));

0
投票
package com.example.demo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.el.stream.Optional;
import org.springframework.expression.spel.ast.OpAnd;
import org.springframework.util.comparator.Comparators;



public class Java8Test {
    

    public static void main(String[] args) {
    
    int[] arr = new int[] {3,98,4,1,3,5,7,9,8,7,6,55,44,33,22,34};
    
     Arrays.stream(arr).filter(x->x%2==0).forEach(action -> {
         System.out.println("Array event number : " +action);
     });
        
    List<Employee> empList = new ArrayList<Employee>();
    empList.add(new Employee(101, "siva", 101, "active", 2000));
    empList.add(new Employee(102, "ready", 101, "active", 5000));
    empList.add(new Employee(103, "raju", 102, "inactive", 6000));
    empList.add(new Employee(104, "sunder", 102, "inaactive", 4000));
    empList.add(new Employee(105, "sunil", 103, "active", 3500));
    empList.add(new Employee(106, "sunath", 103, "inactive", 4200));
    empList.add(new Employee(107, "suresh", 104, "active", 2050));
     
    
    Map<Integer, java.util.Optional<Employee>> mapMaxSalByDept= empList.stream().collect(Collectors.groupingBy(
            Employee::getEmpDepId, Collectors.reducing(BinaryOperator.maxBy(Comparator.comparing(Employee::getEmpSalary)))));
    
    mapMaxSalByDept.entrySet().forEach(action-> {
        System.out.println("DEMP Id : " + action.getKey()+ "Empl Details : "+ action.getValue());
    });
    
    //nth max salary n=3
    Stream<Employee> mapMaxSalByDept1Nth= empList.stream().sorted(Comparator.comparing(Employee:: getEmpSalary).reversed()).limit(3).skip(2);
    mapMaxSalByDept1Nth.forEach(action-> {
        System.out.println("Empl Details : "+ action);
    });
    
    }
    } 


package com.example.demo;

public class Employee {

    private int empId;
    private String empName;
    private int empDepId;
    private String status="active";
    private int empSalary;
    
    public Employee(int empId, String empName, int empDepId, String status, int empSalary) {
        super();
        this.empId = empId;
        this.empName = empName;
        this.empDepId = empDepId;
        this.status = status;
        this.empSalary = empSalary;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + empDepId;
        result = prime * result + empId;
        result = prime * result + ((empName == null) ? 0 : empName.hashCode());
        result = prime * result + empSalary;
        result = prime * result + ((status == null) ? 0 : status.hashCode());
        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 (empDepId != other.empDepId)
            return false;
        if (empId != other.empId)
            return false;
        if (empName == null) {
            if (other.empName != null)
                return false;
        } else if (!empName.equals(other.empName))
            return false;
        if (empSalary != other.empSalary)
            return false;
        if (status == null) {
            if (other.status != null)
                return false;
        } else if (!status.equals(other.status))
            return false;
        return true;
    }

    public int getEmpId() {
        return empId;
    }

    public void setEmpId(int empId) {
        this.empId = empId;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public int getEmpDepId() {
        return empDepId;
    }

    public void setEmpDepId(int empDepId) {
        this.empDepId = empDepId;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int getEmpSalary() {
        return empSalary;
    }

    public void setEmpSalary(int empSalary) {
        this.empSalary = empSalary;
    }

    @Override
    public String toString() {
        return "Employee [empId=" + empId + ", empName=" + empName + ", empDepId=" + empDepId + ", status=" + status
                + ", empSalary=" + empSalary + "]";
    }
    
    
    
}

0
投票
Get Top 2 employees based on salary for each department

   Comparator<Employee> bySalary = 
       Comparator.comparing(Employee::getSalary);
   employeeList.stream().sorted(bySalary)
      .collect(Collectors.groupingBy(e->e.getDepartment()))
      .entrySet().stream()
      .collect(Collectors.toMap(Map.Entry::getKey, 
                                v->v.getValue().subList(0, 2),(a,b) -> a))
                .forEach((k,v)->System.out.println("K "+k+" - V "+v));

0
投票

与其他解决方案相比,这可能是一个简单的解决方案。 这里只使用两个部门..

Mapmap = list.stream().collect(Collectors.groupingBy(Employee::getDeptName, Collectors.maxBy(Comparator.comparing(Employee :: getSalary))));


-1
投票
List<Employee> employeeList = new ArrayList<>();

employeeList.add(new Employee("Mayur", "IT", "100", 1000));
employeeList.add(new Employee("Raj", "IT", "101", 2000));
employeeList.add(new Employee("Anshul", "IT", "102", 3000));
employeeList.add(new Employee("Hari", "EC", "102", 3000));
employeeList.add(new Employee("Ram", "EC", "102", 3000));

Map<String, Optional<Employee>> map = employeeList.stream().collect(Collectors.groupingBy(Employee::getDepartment, Collectors.maxBy(Comparator.comparingInt(Employee::getSalary))));
        map.entrySet().forEach(System.out::println);

输出:

IT=Optional[Employee{name='Anshul', department='IT', employeeID='102', salary=3000}]
EC=Optional[Employee{name='Hari', department='EC', employeeID='102', salary=30000}]
© www.soinside.com 2019 - 2024. All rights reserved.