如何在Java中组合两个不同的Map?

时间:2018-07-25 21:25:12

标签: java java-8

我关注了许多这样的链接Merging two Maps,但仍无法解决问题。

我有两个地图List<Map<String, Object>>-此地图包含acc_num, parent_acc_num, crte_dt, rnwl_dt, userid等,而其他地图包含acc_numisActive(这是从第一张地图)。

我想创建/合并这两个地图,并创建包含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}

另一个查询: 如果以下方法可行,则可能无需进行计算

我有以下使用12c的Oracle查询,我需要一种方法来检查查询本身是否

  1. 如果CreatedDate + 30 days> Sysdate,则显示列为真--->在Trail
  2. 如果CreatedDate + 30天超出跟踪期限
  

“从CUST_ACCT客户中选择cust.acc_num,third.parent_acc_id,cust.crte_dt,cust.updated_dt,cust.crte_user_id,ThirdParty_third第三”   +“其中cust.updated_dt为空,而cust.CRTE_DT

3 个答案:

答案 0 :(得分:1)

假设您的列表仅包含两个地图,并且它们都是可变的。您可以做的是,当且仅当第二个地图的映射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());

答案 1 :(得分:1)

这是解决问题的一种方法:

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提供默认值,或者如果找不到该值,则根本就不想将条目添加到地图中,请考虑使用{{1 }}之前添加到地图。

此外,我建议您通过Guide To Java 8 Optional来熟悉Optional API,当然还要熟悉java documentation!

答案 2 :(得分:0)

我会创建一个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}}