Сопоставление всех полей объекта DTO из другого набора результатов потока (разные результаты базы данных) в Java

У меня есть объект ItemDTO, и некоторые поля содержат данные из базы данных BigQuery, а некоторые из базы данных DB2. Я хочу получить данные и объединить их с объектом DTO с помощью потоков, но это не так, как ожидалось.

Таблица BigQuery включает данные в виде:

Данные таблицы DB2:

Ожидаемый результат: объединение всех полей:

Я использовал потоки для выполнения слияния:

public static class ItemDTO {

        String itemNumber;
        String itemName;
        int postcode;
        String location;
        String price;

        //getter & setters 
    }

List<ItemDTO> bigQueryResults = //resultset from BigQueryDB
/*Retrieved bigquery results: [{
"itemNumber":"101"
"Name":"chair"
"Postcode":"4513"
"Location":null
"Price":null
},
{
"itemNumber":"102"
"Name":"Table"
"Postcode":"2341"
"Location":null
"Price":null
}]*/


List<ItemDTO> db2Results = //resultset from DB2
/*Retrieved db2 results: [{
"itemNumber":"102"
"Name":null
"Postcode":null
"Location":"New York"
"Price":"120"
},
{
"itemNumber":"101"
"Name":null
"Postcode":null
"Location":"Amsterdam"
"Price":"250"
}]*/

// retrieving a list of combined results from both db2 and BQ with key as itemNumber
 List<ItemDTO> resultList = db2List.stream()
                .filter(a -> bqList.stream().anyMatch(item -> item.getItem_nbr().equals(a.getItem_nbr())))
                .collect(Collectors.toList());

/* Expected Output: [{
"itemNumber":"101"
"Name":"chair"
"Postcode":"4513"
"Location":"Amsterdam"
"Price":"250"
},
{
"itemNumber":"102"
"Name":"Table"
"Postcode":"2341"
"Location":"New York"
"Price":"120"
}]*/

/* ResultList output: [{
"itemNumber":"101"
"Name":"chair"
"Postcode":"4513"
"Location":null
"Price":null
},
{
"itemNumber":"102"
"Name":"Table"
"Postcode":"2341"
"Location":null
"Price":null
}]*/


Но когда я использую это, я получаю строки только с сопоставленными значениями для полей BigQuery. Поля, присутствующие в DB2, заполняются как пустые. Пожалуйста, дайте мне знать, есть ли другой способ справиться с таким сопоставлением. Мы ценим любые предложения.

Вам также необходимо показать образцы того, что находится в списках, которые вы транслируете. Помните, что другие люди будут искать на этом сайте ответы на похожие вопросы. Эта информация прояснит, что происходит.

WJS 24.04.2024 16:45

Извините, но размещение изображений не помогает (и в SO это очень не одобряется). Просто покажите списки, заполненные экземплярами данных, например bigQueryResults = List.of(new ItemDTO(...), new IdemDTO(...)...)

WJS 24.04.2024 17:16

@WJS Обновлен код с примерами выходных данных. и список результатов

sharonm 24.04.2024 19:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
4
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Это объединит все частичные извлечения БД с одним и тем же ItemNumber.

  • Сначала создается карта из bigq, используя номер элемента в качестве ключа.
  • затем через collectingAndThen опубликуйте эту карту процессов, транслируйте dbq
  • для всех предметов с одинаковым идентификатором местоположение и цена задаются из предмета dbq.

Определение класса

class ItemDTO {

    String itemNumber;
    String itemName;
    int postcode;
    String location;
    String price;

    public ItemDTO(String itemNumber, String itemName, int postcode,
            String location, String price) {
        this.itemNumber = itemNumber;
        this.itemName = itemName;
        this.postcode = postcode;
        this.location = location;
        this.price = price;
    }

    public String getItemNumber() {
        return itemNumber;
    }

    public void setItemNumber(String itemNumber) {
        this.itemNumber = itemNumber;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public int getPostcode() {
        return postcode;
    }

    public void setPostcode(int postcode) {
        this.postcode = postcode;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return itemNumber + ", " + itemName + ", " + postcode + ", " + location
                + ", " + price;
    }

}

Процесс

List<ItemDTO> bigQueryResults = List.of(
        new ItemDTO("101", "chair", 4513, null, null),
        new ItemDTO("102", "Table", 2341, null, null),
        new ItemDTO("103", "Television", 5607, null, null),
        new ItemDTO("104", "Microwave", 2378, null, null),
        new ItemDTO("105", "Sofa", 1278, null, null));

List<ItemDTO> dbQueryResults = List.of(
        new ItemDTO("102", null, 0, "New York", "120"),
        new ItemDTO("106", null, 0, "Budapest", "300"),
        new ItemDTO("101", null, 0, "Amsterdam", "250)"));

// retrieving the db2 results for itemNumbers from bigQueryResults
List<ItemDTO> mergedResult = bigQueryResults.stream()
        .collect(Collectors.collectingAndThen(
           Collectors.groupingBy(ItemDTO::getItemNumber),
           mp -> dbQueryResults.stream().<ItemDTO>mapMulti((item, consumer) -> {
               List<ItemDTO> sameNumberList = mp.get(item.getItemNumber());
               if (sameNumberList != null) { // item number may not be
                                             // in map  
                  for (ItemDTO i : sameNumberList) {
                    i.setLocation(item.getLocation());
                    i.setPrice(item.getPrice());
                    consumer.accept(i); // put updated item on stream
                  }
               }
          }))).toList();

mergedResult.forEach(System.out::println);

печатает следующее для предоставленных данных

102, Table, 2341, New York, 120
101, chair, 4513, Amsterdam, 250)

Рекомендую посмотреть картуMulti , CollectingAndThen , Collectors.groupingBy

Обновлен ответ для Java-8.

  • первая группаКак и раньше
  • затем переберите два списка и добавьте измененный ItemDTO в объединенный список результатов.
Map<String, List<ItemDTO>> mapByItemNumber = bigQueryResults.stream()
        .collect(Collectors.groupingBy(ItemDTO::getItemNumber));

List<ItemDTO> mergedResults = new ArrayList<>();

for (ItemDTO item : dbQueryResults) {
    if (mapByItemNumber.containsKey(item.getItemNumber())) {
        for (ItemDTO i : mapByItemNumber.get(item.getItemNumber())) {
            i.setLocation(item.getLocation());
            i.setPrice(item.getPrice());
            mergedResults.add(i);
        }
    }
}

mergedResults.forEach(System.out::println);

Спасибо за ответ. Но я использую Java 8

sharonm 24.04.2024 19:37

@sharonm Вы видели мой обновленный ответ? Это работает для Java-8.

WJS 25.04.2024 20:35

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