Я перешел по многим таким ссылкам Слияние двух карт, но пока не смог решить проблему.
У меня есть две карты List<Map<String, Object>> - эта карта содержит acc_num, parent_acc_num, crte_dt, rnwl_dt, userid и т. д., А другая карта содержит acc_num и isActive (это больше уточнение из 1-й карты).
Я хотел создать / объединить эти две карты и создать окончательную карту, которая содержит детали acc_num, parent_acc_num, crte_dt, rnwl_dt, userid + isActive.
Как я могу это сделать ?
Ниже приведен образец данных. Единственная проблема в том, что оба являются списком карт, как перебирать один за другим?
{CRTE_DT=2017-06-22, USER_ID=ABC, ACC_NUM=9449, RNWL_DT=2017-06-22, PARENT_ACC_NO=9449}
{ACC_NUM=9449, IS_ACTIVE=false}
Другой запрос: Если приведенное ниже работает, возможно, нет необходимости в расчетах.
У меня есть запрос Oracle ниже с использованием 12c, мне нужен способ проверить сам запрос, если
"select cust.acc_num, third.parent_acc_id, cust.crte_dt,cust.updated_dt ,cust.crte_user_id from CUST_ACCT cust, ThirdParty_third third " + "where cust.updated_dt is null and cust.CRTE_DT < sysdate " + "and cust.acc_num = third.third_code and is_actv = ? union " + "select cust.acc_num, third.parent_acc_id, cust.crte_dt,cust.updated_dt, cust.crte_user_id from CUST_ACCT cust, ThirdParty_third third " + "where ( cust.updated_dt is not null and cust.updated_dt < sysdate ) " + "and cust.acc_num = third.third_code and is_actv = ? ";
да с использованием учетной записи Нет, оба являются списками карты
Для каждого объекта значения карты различаются, и если вы хотите объединить карты, вам понадобится новый тип объекта, который содержит данные обоих предыдущих. Покажи нам эти предметы. Кроме того, содержит ли список 2 элемента? Если да, то зачем вам список?




Я бы создал Map<Integer,Map<String,Object>>, чтобы помочь. "acct_num" - это ключ, общий для обеих ваших карт, поэтому вы будете использовать его, чтобы сопоставить их.
Шаги:
"is_active" из второго списка к значению, которое вы только что нашли на карте.values() из вашей вспомогательной карты, и у вас будет список карт с объединенными значениями.Код будет выглядеть примерно так:
a = [CRTE_DT:"2017-06-22", USER_ID:"ABC", ACC_NUM:9449, RNWL_DT:"2017-06-22", PARENT_ACC_NO:9449]
b = [ACC_NUM:9449, IS_ACTIVE:false]
list1 = [a]
list2 = [b]
c = new HashMap<Integer,Map<String,Object>>()
for ( Map<String,Object> r : list1 ) {
c.put(r.get("ACC_NUM"),r)
}
for (Map<String,Object> r : list2 ) {
d = c.get(r.get("ACC_NUM"));
if (d != null) d.putAll(r);
}
groovy:000> c
===> {9449 = {CRTE_DT=2017-06-22, USER_ID=ABC, ACC_NUM=9449, RNWL_DT=2017-06-22, PARENT_ACC_NO=9449, IS_ACTIVE=false}}
Предположим, что ваш список содержит только две карты, и обе они изменяемы. Что вы можете сделать, так это добавить все сопоставления второй карты к первой тогда и только тогда, когда вторая карта имеет сопоставление ACC_NUM, равное первому.
final List<Map<String, Object>> maps = ...;
if (Optional.ofNullable(map.get(1).get("ACC_NUM")).filter(acc_num -> acc_num.equals(map.get(0).get("ACC_NUM"))).isPresent())
{
map.get(0).putAll(map.get(1));
}
РЕДАКТИРОВАТЬ
final List<Map<String, Object>> l1 = ...;
final List<Map<String, Object>> l2 = ...;
final List<Map<String, Object>> result = l1.stream()
.map(map ->
{
final Map<String, Object> r = new HashMap<>(map);
l2.stream()
.filter(map2 -> Objects.equals(map.get("ACC_NUM"), map2.get("ACC_NUM")))
.findFirst()
.map(map2 -> map2.get("IS_ACTIVE"))
.ifPresent(is_active -> map.put("IS_ACTIVE", is_active));
return r;
})
.collect(Collectors.toList());
@Prateek, вы можете проверить мою правку, она частично эквивалентна Ответ Аомине.
@ marsouf - Большое вам спасибо. +1, не могли бы вы также опубликовать ответ без java 8?
Вот один из способов сделать это:
List<Map<String, Object>> map3 = new ArrayList<>();
l1.forEach(map -> {
// clone the map to avoid mutating existing maps
Map<String, Object> temp = new HashMap<>(map);
// get the corresponding match in the second list
Optional<Object> value = l2.stream()
.filter(m -> m.containsValue(map.get("ACC_NUM")))
.findFirst().map(c -> c.get("IS_ACTIVE"));
temp.put("IS_ACTIVE", value.get()); // insert the new entry
map3.add(temp); // add the new map to the accumulator
});
По сути, это перечисляет каждую карту в l1 (первый список) и клонирует всю карту в новый экземпляр карты и просто вставляет новую запись в эту новую карту, где ключ - "IS_ACTIVE", а значение - то, что мы находим в l2 (второй список).
Это решение предполагает, что всегда будет соответствующее совпадение в l2, следовательно, вызов get() для результата Optional<T>. однако если это не так, вы можете использовать Optional#orElse для предоставления значения по умолчанию, или если значение не найдено, вы просто не хотите добавлять запись на карту вообще, рассмотрите возможность использования Optional#isPresent перед добавлением на карту .
Кроме того, я бы рекомендовал пройти через Руководство по Java 8 (необязательно), чтобы ознакомиться с дополнительным API и, конечно же, с документация java!.
Мне нравится, что здесь используются новые потоковые API :-) - но я думаю, что это может быть O (n * m), в то время как у меня, старомодно, должно быть только O (m + n) ...
Две карты или два списка? Как вы хотите слить
acc_num? Что ты пробовал? Где ты застрял?