模型中的Java Lambda流合并参数

时间:2019-02-06 10:18:39

标签: java lambda collections java-8 java-stream

我找不到答案。 我尝试将多个对象合并到一个。 示例模型

public class Model {
    private List<Map<String, Object>> param1;
    private List<String> param2;
}

在我的代码中,我将另一个数据转换为模型。

List<Model> models = models2.stream()
    .map(Optional::get)
    .map(model2 -> convert(model2))
    .collect(Collectors.toList()); 

我尝试将转换后的模型列表聚合为一个模型。 喜欢:

Model model = models2.stream() ...etc

但我不知道如何。

2 个答案:

答案 0 :(得分:1)

最简单的方法是将merge方法添加到您的Model类中:

public class Model {
    private List<HashMap<String, Object>> param1;
    private List<String> param2;

    public Model merge (Model other) {
        this.param1.addAll(other.param1);
        this.param2.addAll(other.param2);

        return this;
    }
}

然后reduce您的流:

Model allInOne = models2.stream()
    .map(Optional::get)
    .map(model2 -> convert(model2))
    .reduce(Model::merge)
    .get();

merge方法也可以是static Model merge (Model first, Model second)或外部化的BinaryOperator<Model>函数。

答案 1 :(得分:0)

首先,您当前的代码包含一个隐藏的明显错误。遇到空的Optional::get时,操作Optional将引发异常。您应该先过滤掉空的可选内容:

// ...
.filter(Optional::isPresent)
.map(Optional::get)
// ...

或者,如果您使用的是java-9或更高版本,则可以简单地映射可选值:

// ...
.flatmap(Optional::stream)
// ...   

对于您的问题,您似乎需要reduce使用合并功能。定义该功能的方法有多种:

  1. 方法参考:

    private Model merge(Model model1, Model model2) {
        // merge model2 to model1
        return model1;
    }
    
    Model model = models2.stream()
            .filter(Optional::isPresent)
            .map(Optional::get)
            .map(this::convert)
            .reduce(this::merge)
            .orElse(defaultModel);
    
  2. 存储在变量中的BinaryOperator

    BinaryOperator<Model> merge = (model1, model2) -> { /* do smth */; return model1;}  
    
    // ... 
    .map(this::convert)
    .reduce(merge)
    //
    
  3. 内联lambda

    // ... 
    .map(this::convert)
    .reduce((model1, model2) -> { /* do smth */; return model1;})
    //
    

恕我直言,第一个选择是最好的。拥有单独的方法将使您的代码更整洁,更易于维护。