Java 8 使用过滤器选项在嵌套列表中执行求和运算

标签 java lambda java-8 java-stream

假设我有以下构造:

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/

相关文章:

java - 从嵌套可选检查中的列表中获取元素

java - 从 Servlet 输出 SoyTemplates 的最佳方式

java - 由于 java.lang.NoClassDefFoundError : com/fasterxml/jackson/annotation/JsonMerge 无法运行代码

c++ - Lambda 捕获数组元素失败

c++ - 如何将可调用对象放入 C++ 中的映射中?

java - 如何将值集合绑定(bind)到 jOOQ 批量插入

java - 如何正确地将文件数组传输到另一个 Activity ?

java - 无法安装JDK

lambda - Intellij 中的 Java Lambda : Expected not null but the lambda body is not value-compatible

java - Java 8 中是否有等效于 Scala 的 Either?