使用流查找 Employee 及其 Parent 的值总和
Find the sum of values of an Employee and its Parent using stream
考虑一下,我有以下 class.
public class Employee {
private Integer id;
private Integer parentId;
private int value;
}
现在我有以下记录。
Employee employee1 = new Employee(1, null, 4);
Employee employee2 = new Employee(2, 1, 4);
Employee employee3 = new Employee(3, null, 8);
Employee employee4 = new Employee(4, 1, 3);
Employee employee5 = new Employee(5, 2, 11);
所以 parentId
是 员工 的 id
,他是另一个 员工 的老板。
问题是找出 employee 的价值的 sum 和它是父级(如果有的话),或者 return 原样的值。所以在这种情况下,结果应该是。
id
value
1
4
2
8
3
8
4
7
5
15
如何使用 java 8 个流实现此目的?我尝试了以下方法;
Optional<Integer> first = employees.stream().map(a -> {
int sum = 0;
employees.stream().map(b -> {
if (Objects.equals(a.id, b.parentId)) {
sum = sum + a.value + b.value;
}else{
sum = sum + a.value;
}
return sum;
});
return sum;
}
).findFirst();
但是我在 sum 变量上遇到错误,它应该是最终的或实际上是最终的。
通过仅计算子项及其第一个父项的值,您可以使用列表中的简单过滤器来完成。
@Test
public void test() {
final Employee employee1 = new Employee(1, null, 4);
final Employee employee2 = new Employee(2, 1, 4);
final Employee employee3 = new Employee(3, null, 8);
final Employee employee4 = new Employee(4, 1, 3);
final Employee employee5 = new Employee(5, 2, 11);
final List<Employee> employees = List.of(employee1, employee2, employee3, employee4, employee5);
final List<Pair<Integer, Integer>> res = employees
.stream()
.map(emp -> Pair.of(emp.id,
emp.value + employees
.stream()
.filter(e -> e.id.intValue() == Optional.ofNullable(emp.parentId).orElse(-1))
.findFirst().map(Employee::getValue)
.orElse(0)
)
)
.collect(Collectors.toList());
res.forEach(System.out::println);
}
public class Employee {
public Integer id;
public Integer parentId;
public int value;
public Employee(final Integer id, final Integer parentId, final int value) {
this.id = id;
this.parentId = parentId;
this.value = value;
}
public int getValue() {
return this.value;
}
}
结果:
(1,4)
(2,8)
(3,8)
(4,7)
(5,15)
注意:我使用的对象 Pair 来自 org.apache.commons.lang3.tuple.Pair
实现这一点的最有效方法是创建一个 map,它将允许检索 value
Employee
由其 id
.
然后,为了将每个 Employee
的 value
与其父级的 value
相结合,使用 值 38=]map 或 0
如果 parent 是 null
.
下面的方法生成一个 map,其中 id
用作 key,员工的 value
作为 值.
public static Map<Integer, Integer> getEmplValueById(List<Employee> employees) {
return employees.stream()
.collect(Collectors.toMap(Employee::getId,
Employee::getValue));
}
以下方法创建了一个 map,其中 id
用作 key 并且 员工的总价值作为地图的价值。
public static Map<Integer, Integer> getEmplSumById(List<Employee> employees,
Map<Integer, Integer> valueById) {
return employees.stream()
.collect(Collectors.toMap(Employee::getId,
empl -> empl.getValue() +
valueById.getOrDefault(empl.getParentId(), 0)));
}
main()
public static void main(String[] args) {
List<Employee> employees = List.of(
new Employee(1, null, 4),
new Employee(2, 1, 4),
new Employee(3, null, 8),
new Employee(4, 1, 3),
new Employee(5, 2, 11));
Map<Integer, Integer> valueById = getEmplValueById(employees);
getEmplSumById(employees, valueById)
.forEach((k, v) -> System.out.printf("ID %d \t value %d\n", k, v));
}
输出
ID 1 value 4
ID 2 value 8
ID 3 value 8
ID 4 value 7
ID 5 value 15
考虑一下,我有以下 class.
public class Employee {
private Integer id;
private Integer parentId;
private int value;
}
现在我有以下记录。
Employee employee1 = new Employee(1, null, 4);
Employee employee2 = new Employee(2, 1, 4);
Employee employee3 = new Employee(3, null, 8);
Employee employee4 = new Employee(4, 1, 3);
Employee employee5 = new Employee(5, 2, 11);
所以 parentId
是 员工 的 id
,他是另一个 员工 的老板。
问题是找出 employee 的价值的 sum 和它是父级(如果有的话),或者 return 原样的值。所以在这种情况下,结果应该是。
id | value |
---|---|
1 | 4 |
2 | 8 |
3 | 8 |
4 | 7 |
5 | 15 |
如何使用 java 8 个流实现此目的?我尝试了以下方法;
Optional<Integer> first = employees.stream().map(a -> {
int sum = 0;
employees.stream().map(b -> {
if (Objects.equals(a.id, b.parentId)) {
sum = sum + a.value + b.value;
}else{
sum = sum + a.value;
}
return sum;
});
return sum;
}
).findFirst();
但是我在 sum 变量上遇到错误,它应该是最终的或实际上是最终的。
通过仅计算子项及其第一个父项的值,您可以使用列表中的简单过滤器来完成。
@Test
public void test() {
final Employee employee1 = new Employee(1, null, 4);
final Employee employee2 = new Employee(2, 1, 4);
final Employee employee3 = new Employee(3, null, 8);
final Employee employee4 = new Employee(4, 1, 3);
final Employee employee5 = new Employee(5, 2, 11);
final List<Employee> employees = List.of(employee1, employee2, employee3, employee4, employee5);
final List<Pair<Integer, Integer>> res = employees
.stream()
.map(emp -> Pair.of(emp.id,
emp.value + employees
.stream()
.filter(e -> e.id.intValue() == Optional.ofNullable(emp.parentId).orElse(-1))
.findFirst().map(Employee::getValue)
.orElse(0)
)
)
.collect(Collectors.toList());
res.forEach(System.out::println);
}
public class Employee {
public Integer id;
public Integer parentId;
public int value;
public Employee(final Integer id, final Integer parentId, final int value) {
this.id = id;
this.parentId = parentId;
this.value = value;
}
public int getValue() {
return this.value;
}
}
结果:
(1,4)
(2,8)
(3,8)
(4,7)
(5,15)
注意:我使用的对象 Pair 来自 org.apache.commons.lang3.tuple.Pair
实现这一点的最有效方法是创建一个 map,它将允许检索 value
Employee
由其 id
.
然后,为了将每个 Employee
的 value
与其父级的 value
相结合,使用 值 38=]map 或 0
如果 parent 是 null
.
下面的方法生成一个 map,其中 id
用作 key,员工的 value
作为 值.
public static Map<Integer, Integer> getEmplValueById(List<Employee> employees) {
return employees.stream()
.collect(Collectors.toMap(Employee::getId,
Employee::getValue));
}
以下方法创建了一个 map,其中 id
用作 key 并且 员工的总价值作为地图的价值。
public static Map<Integer, Integer> getEmplSumById(List<Employee> employees,
Map<Integer, Integer> valueById) {
return employees.stream()
.collect(Collectors.toMap(Employee::getId,
empl -> empl.getValue() +
valueById.getOrDefault(empl.getParentId(), 0)));
}
main()
public static void main(String[] args) {
List<Employee> employees = List.of(
new Employee(1, null, 4),
new Employee(2, 1, 4),
new Employee(3, null, 8),
new Employee(4, 1, 3),
new Employee(5, 2, 11));
Map<Integer, Integer> valueById = getEmplValueById(employees);
getEmplSumById(employees, valueById)
.forEach((k, v) -> System.out.printf("ID %d \t value %d\n", k, v));
}
输出
ID 1 value 4
ID 2 value 8
ID 3 value 8
ID 4 value 7
ID 5 value 15