Как объединить 2 списка объектов на основе определенного поля и независимо от значений

У меня есть два списка объектов Dto, оба они получены из разных запросов BQ. Пример:

Список результатов BQ 1:

List<Data> bq1 = {
  [name:"abc", country: "ca", nbr:334],
  [name:"dcc", country: "ca", nbr:222], 
  [name:"aop", country: "in", nbr:234]
}

Список результатов BQ 2:

List<Data> bq2 = {
  [color:a,  nbr:334],
  [color:n, nbr:334], 
  [color:e, nbr:234]
}

Я хочу объединить оба списка на основе значения nbr и создать новый список.

ожидал:

List<Data> result = {
  [name:"aop", country: "in", nbr:234, color: e], 
  [name:"abc", country: "ca", nbr:334, color: a], 
  [name:"abc", country: "ca", nbr:334, color: n]
}

Но когда у вас более одной записи с одинаковым nbr, я получаю повторяющийся только один набор значений.

Существующий результат:

List<Data> result = {
  [name:"aop", country: "in", nbr:234, color: e], 
  [name:"abc", country: "ca", nbr:334, color: a], 
  [name:"abc", country: "ca", nbr:334, color: a]
}

Я использую Java8, буду благодарен за любую помощь. Спасибо

List<Data> resultList = new ArrayList<>();

Map<String, List<Data>> mapByItemNumber = bqList.stream()
    .collect(Collectors.groupingBy(Data::getNbr));

for (Data item : bq3List) {

    if (mapByItemNumber.containsKey(item.getNbr())) {

        for (Data i : mapByItemNumber.get(item.getNbr())) {

            i.setColor(item.getColor());  
            resultList.add(i);
        }
    }
}

Пожалуйста, создайте полную, минимальную, работоспособную программу, которая иллюстрирует проблему.

tgdavies 20.05.2024 07:25

Я могу получить список объектов, но для определенного идентификатора, если есть 3 записи с разными значениями полей, только одна запись печатается трижды. Любая помощь по этому вопросу будет оценена по достоинству.

neha menezes 21.05.2024 10:45

Любое решение поможет

neha menezes 23.05.2024 10:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот протестированное решение для вашего запроса: добавлен новый конструктор со всеми значениями и сопоставленными с ним данными элемента:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {

        List<Data> bq1 = List.of(new Data("abc", "ca", 334), new Data("dc", "ca", 222), new Data("aop", "in", 234));
        List<Data> bq2 = List.of(new Data("a", 334), new Data("n", 334), new Data("e", 234));

        Map<Integer, List<Data>> mapByItemNumber = bq2.stream().collect(Collectors.groupingBy(Data::getNbr));

        List<Data> result = new ArrayList<>();

        for (Data data : bq1) {

            if (mapByItemNumber.containsKey(data.getNbr())) {
                
                List<Data> list = mapByItemNumber.get(data.getNbr());
                
                List<Data> collect = list.stream()
                        .map(item -> new Data(data.getName(), data.getCountry(), data.getNbr(), item.getColor()))
                        .collect(Collectors.toList());
                
                result.addAll(collect);
            }
        }
        
        System.out.println(result);
        //output::
        //[Data [name=abc, country=ca, nbr=334, color=a],
        //Data [name=abc, country=ca, nbr=334, color=n], 
        //Data [name=aop, country=in, nbr=234, color=e]]

    }

}

class Data {

    private String name;
    private String country;
    private int nbr;
    private String color;

    public Data(String name, String country, int nbr) {
        super();
        this.name = name;
        this.country = country;
        this.nbr = nbr;
    }

    public Data(String name, String country, int nbr, String color) {
        super();
        this.name = name;
        this.country = country;
        this.nbr = nbr;
        this.color = color;
    }

    public Data(String color, int nbr) {
        super();
        this.nbr = nbr;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public int getNbr() {
        return nbr;
    }

    public void setNbr(int nbr) {
        this.nbr = nbr;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    @Override
    public String toString() {
        return "Data [name = " + name + ", country = " + country + ", nbr = " + nbr + ", color = " + color + "]";
    }

}

Привет. спасибо за ответ, но что, если у меня в Data dto более 50 полей. Нужно ли мне получить все 50+ полей в строке .map(item -> new Data(dat....

neha menezes 20.05.2024 10:57

Вместо конструктора вы можете использовать lombok с @Builder на уровне класса и создавать из него объект, а если вы хотите выполнить какую-либо операцию во время создания объекта, просто создайте метод, который возвращает тип данных, и передайте этот метод на карте, например: .map (пункт -> createDataObj (передайте сюда аргументы)). И если мой ответ решит вашу проблему, попросите вас проголосовать за него или принять его по своему усмотрению.

Vinayak Nair 20.05.2024 11:02

Другие вопросы по теме