Как совместить две разные карты в java?

Я перешел по многим таким ссылкам Слияние двух карт, но пока не смог решить проблему.

У меня есть две карты 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, мне нужен способ проверить сам запрос, если

  1. Если CreatedDate + 30 days> Sysdate, отобразить столбец с истинным значением ---> In Trail
  2. Если CreatedDate + 30 days <Sysdate, тогда показывать столбец, имеющий false ---> Out of Trail Period

"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 = ? ";

Две карты или два списка? Как вы хотите слить acc_num? Что ты пробовал? Где ты застрял?

shmosel 25.07.2018 23:27

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

Jeff Cook 25.07.2018 23:29

Для каждого объекта значения карты различаются, и если вы хотите объединить карты, вам понадобится новый тип объекта, который содержит данные обоих предыдущих. Покажи нам эти предметы. Кроме того, содержит ли список 2 элемента? Если да, то зачем вам список?

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

Ответы 3

Я бы создал Map<Integer,Map<String,Object>>, чтобы помочь. "acct_num" - это ключ, общий для обеих ваших карт, поэтому вы будете использовать его, чтобы сопоставить их. Шаги:

  • перебирать первый список, добавляя каждый элемент на карту, используя его acc_num в качестве ключа.
  • перебрать второй список, используя значение 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 27.07.2018 10:43

@ marsouf - Большое вам спасибо. +1, не могли бы вы также опубликовать ответ без java 8?

Jeff Cook 28.07.2018 17:01

Вот один из способов сделать это:

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) ...

moilejter 27.07.2018 03:45

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