如何使用java流将嵌套for循环转换为Hashmap [英] How to convert nested for loop into Hashmap using java stream
问题描述
我正在尝试使用java流将下面嵌套的for循环转换为hashmap但是我在收集器步骤中受到了冲击。你可以帮忙吗?
I am trying to convert the below nested for loop into hashmap using java stream but i got struck in the collector step. Could you please help?
现有代码:
private static HashMap<String, Long> getOutput(List<Employee> eList) {
HashMap<String, Long> outputList = new HashMap<>();
for (Employee employee : eList) {
List<Department> departmentList = employee.getDepartmentList();
for (Department department : departmentList) {
if (department.getType().equals(DepartmentType.SCIENCE)) {
outputList.put(employee.getName(),department.getDepartmentId()));
}
}
}
return outputList;
}
到目前为止我尝试过:
private static HashMap<String, Long> getOutput(List<Employee> eList) {
return eList.stream()
.flatMap(emp -> emp.getDepartmentList().stream()
.filter(dept -> dept.getType().equals(DepartmentType.SCIENCE))
.collect(HashMap::new, ???)
}
推荐答案
看来你的主要问题是保留了流的当前 emp
之后的参考你已经完成了 flatMap
。为了保留这个参考,你需要 flatMap
到某种类可以持有员工和部门 - 例如通用的元组(又名配对)。
It seems like your main issue is preserving the stream's current emp
reference after you've done the flatMap
. To keep this reference, you will need to flatMap
to some sort of class that can hold both the Employee and Department - such as a generic Tuple (aka Pair).
Java没有内置于其API中的直观Tuple类,因此您可以选择:
Java doesn't have an intuitive Tuple class built into it's API, so your options are:
- 使用第3页的第三方库提供一个元组类(例如 javatuples )
- DIY:构建您自己的通用Tuple类(请参阅相关的 SO问题)
- 快速:添加一个特定用途的私有内部类这个lambda
编辑:
评论(感谢@Holger!)已经明白,每个员工似乎有很多部门。我的原始代码冒着抛出异常的风险,因为会有重复的密钥,而OP的原始代码只会覆盖映射条目。考虑使用 groupingBy
收集器并更改此方法的返回类型。
The comments (thanks @Holger!) have enlightened that it appears that there are many departments per employee. My original code risks throwing an exception since there would be duplicate keys, while the OP's original code simply overwrites the map entries. Consider using the groupingBy
collector and changing the return type of this method.
private static Map<String, List<Long>> getOutput(List<Employee> eList) {
return eList.stream()
// get a stream of employee / department pairs
.flatMap(emp -> emp.getDepartmentList().stream().map(dep -> new EmployeeDepartmentPair(emp, dep))
// filter the departments to SCIENCE
.filter(x -> x.department.getType().equals(DepartmentType.SCIENCE))
// group departmentIds by employee name
.collect(Collectors.groupingBy(x -> x.employee.getName(), Collectors.mapping(x -> x.department.getDepartmentId(), Collectors.toList())))
}
原文(见上文编辑):
以下是使用选项3的一些更新代码:
Here's some updated code using option 3:
private static Map<String, Long> getOutput(List<Employee> eList) {
return eList.stream()
.flatMap(emp -> emp.getDepartmentList().stream().map(dep -> new EmployeeDepartmentPair(emp, dep))
.filter(x -> x.department.getType().equals(DepartmentType.SCIENCE))
.collect(Collectors.toMap(x -> x.employee.getName(), x -> x.department.getDepartmentId()));
}
private static class EmployeeDepartmentPair {
public final Employee employee;
public final Department department;
public EmployeeDepartmentPair(Employee emp, Department d) {
this.employee = emp;
this.department = d;
}
}
这篇关于如何使用java流将嵌套for循环转换为Hashmap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!