У меня есть объект 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, заполняются как пустые. Пожалуйста, дайте мне знать, есть ли другой способ справиться с таким сопоставлением. Мы ценим любые предложения.
Вам также необходимо показать образцы того, что находится в списках, которые вы транслируете. Помните, что другие люди будут искать на этом сайте ответы на похожие вопросы. Эта информация прояснит, что происходит.
Извините, но размещение изображений не помогает (и в SO это очень не одобряется). Просто покажите списки, заполненные экземплярами данных, например bigQueryResults = List.of(new ItemDTO(...), new IdemDTO(...)...)
@WJS Обновлен код с примерами выходных данных. и список результатов
Это объединит все частичные извлечения БД с одним и тем же 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 Вы видели мой обновленный ответ? Это работает для Java-8.
Задавая подобные вопросы, полезно опубликовать минимально воспроизводимый пример . Как минимум, вы должны предоставить класс DTO, примеры данных, правильно отображаемые на Java, и ожидаемый результат в правильном формате. Пожалуйста, ознакомьтесь с разделом Как спросить и найдите время, чтобы совершить тур.