class Employee {
public string department;
public int salary;
}
List<Employee> allEmployees = ...
我需要一个列表,其中每个部门只有 1 名最高薪员工。 allEmployees 是源列表。
您可以使用分组收集器来做到这一点:
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
来包装它,并使用仅返回员工的完成器:我们知道在这种情况下,可选不会为空。
替代解决方案:
Map<String, Employee> topEmployees =
allEmployees.stream()
.collect(Collectors.toMap(
e -> e.department,
e -> e,
BinaryOperator.maxBy(Comparator.comparingInt(e -> e.salary))
));
当我们遇到部门的第一位员工时,我们会向
Map
添加一个新条目。当找到另一名员工时,工资更高的人会被保留。这样你就不需要干预选项。
/假设您有一个员工列表,如 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);
老实说,这不是一个解决方案。 由于声誉较低,我无法发表评论,这只是一个微小的观察,导致了这次修正/即兴创作。
我遇到了同样的情况,我尝试了上面提到的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());
}
希望这对某人有帮助。谢谢。
Map
每个部门的最高工资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)
)
);
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));
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 + "]";
}
}
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));
与其他解决方案相比,这可能是一个简单的解决方案。 这里只使用两个部门..
Map
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}]