假设我有以下构造:
public class Athlete {
private String name;
private int someIdentifier;
private Double height;
private Double weight;
private List<Shoes> shoes;
// getters
// setters
public class Shoes {
private String name;
private boolean ball;
private int someNumber;
private int someOtherNumber;
// getters
// setters
}
}
我在这里收集了第一次迭代的列表 List<Athlete> athleteList
现在我创建一个新的运动员对象,我想检查它们是否已存在于我的列表中,如果存在,我想对某些字段执行添加操作。
我尝试了以下方法,效果很好:
athleteList.stream()
.filter(at -> filterAthlete(at, newAthlete))
.map(at -> mergeAthletes(at, newAthlete))
.collect(Collectors.toList());
private boolean filterAthlete(Athlete firstAthlete, Athlete secondAthlete) {
if (firstAthlete.getName().equals(secondAthlete.getName())
&& firstAthlete.getSomeIdentifier() == secondAthlete.getSomeIdentifier()) {
return true;
} else {
return false;
}
}
private Athlete mergeAthletes(Athlete firstAthlete, Athlete secondAthlete) {
for (Shoes firstShoe : firstAthlete.getShoes()) {
for (Shoes secondShoe : secondAthlete.getShoes()) {
if (firstShoe.getBrand().equals(secondShoe.getBrand()) && firstShoe.getColor().equals(secondShoe.getColor())) {
firstShoe.setSomeNumber(firstShoe.getSomeNumber() + secondShoe.getSomeNumber());
firstShoe.setSomeOtherNumber(firstShoe.getSomeOtherNumber() + secondShoe.getSomeOtherNumber());
}
}
}
return firstAthlete;
}
但我想找到一种在我的 mergeAthletes(...) 方法中使用 stream() 的方法。
我想做这样的事情:
BiConsumer<Shoes, Shoes> reducer = (shoe1, shoe2) -> {
shoe1.setSomeNumber(shoe1.getSomeNumber() + shoe2.getSomeNumber());
shoe1.setSomeOtherNumber(shoe1.getSomeOtherNumber() + shoe2.getSomeOtherNumber());
};
Function<Shoes, List<Object>> compositeKey = shoes -> Arrays.<Object> asList(shoes.getBrand(),
shoes.getColor());
在我的 mergeAthletes 方法中,使用 Function 代替我的 if 条件,使用 BiConsumer 代替每个循环中 double 的加法,但我还没想好怎么做。
如有任何帮助,我们将不胜感激。
最佳答案
firstAthlete.getShoes().forEach(shoe1 ->
secondAthlete.getShoes().stream().filter(shoe2 ->
shoe1.getBrand().equals(shoe2.getBrand()) && shoe1.getColor().equals(shoe2.getColor()))
).forEach(shoe2 -> {
shoe1.setSomeNumber(shoe1.getSomeNumber() + shoe2.getSomeNumber());
shoe1.setSomeOtherNumber(shoe1.getSomeOtherNumber() + shoe2.getSomeOtherNumber());
})
如果您的鞋子是不可变的(没有 set...
方法),那么您将使用 reduce
而不是第二个 forEach
和可能的 map
而不是第一个,具体取决于您的要求。
(此外,firstAthlete.getName() == secondaryAthlete.getName()
很可能是一个错误,您希望在其中使用 equals
,就像比较鞋子时一样。)
关于Java 8 使用过滤器选项在嵌套列表中执行求和运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47113130/