Параметры лямбда-потока Java в модели - PullRequest
0 голосов
/ 06 февраля 2019

Я не могу найти ответ.Я пытаюсь объединить несколько объектов в один.Пример модели

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 голосов
/ 06 февраля 2019

Прежде всего ваш текущий код содержит скрытую неочевидную ошибку .Операция 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. A 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;})
    //
    

ИМХО первый вариант самый лучший.Наличие отдельного метода сделает ваш код чище и проще в обслуживании.

0 голосов
/ 06 февраля 2019

Самый простой способ - добавить 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> функцией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...