首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在嵌套的Map<String、?>中迭代、查找和更新值

在嵌套的Map<String、?>中迭代、查找和更新值
EN

Stack Overflow用户
提问于 2018-03-14 16:04:37
回答 3查看 2.3K关注 0票数 0

我有一个YML文件,我使用yamlBeans库将其解析为Map。我不知道嵌套的地图有多深。例如:

  • key1:
    • key2: value1
    • key3:
      • key4: value2
      • key5: value3

我需要在这个映射中找到一个特定的值,更新它,并将映射写回YML文件(我知道怎么做)。

这是我更新值的代码,它正在工作。然而,只在嵌套的映射中迭代两次,并且我需要它在需要时迭代它的时间。

代码语言:javascript
复制
    static void updateYmlContent(Map<String, ?> ymlMap, String value, String... keys) {
    boolean found = false;
    for (Map.Entry entry : ymlMap.entrySet()) {
        if (entry.getKey().equals(keys[0])) {
            found = true;
            for (Map.Entry subEntry : ((Map<?, ?>) entry.getValue()).entrySet()) {
                if (subEntry.getKey().equals(keys[1])) {
                    subEntry.setValue(value);
                    break;
                } else {
                    throwKeyNotFoundException(keys[1]);
                }
            }
            break;
        }
    }
    if (!found) {
        throwKeyNotFoundException(keys[0]);
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-14 16:30:10

使用递归和深度计数器通过地图的每一层。我没有编译它,所以它可能需要稍微修改一下,但是下面是基本的想法:

代码语言:javascript
复制
static void updateYmlContent(Map<String, ?> ymlMap, String value, String... keys) {
    int depth = 0;
    findAndReplaceContent(ymlMap, value, keys, depth);
}

static void findAndReplaceContent(Map map, .......) {
  if (map.containsKey(keys[depth]))
  {
    if (depth == keys.length - 1)
    {
      // found it
      map.put(keys[depth], value);
      // done
    }
    else
    {
      findAndReplaceContent(map.get(keys[depth]), value, keys, depth+1);
    }
  }
  else
  {
    // throw key not found
  }
}
票数 0
EN

Stack Overflow用户

发布于 2018-03-14 17:55:56

如果ymlMap是可变的,那么它应该是Map<String, Object>类型(理想情况下),我相信您已经检查过了。

代码语言:javascript
复制
@SuppressWarnings("unchecked")
static void updateYmlContent(Map<String, ?> ymlMap, String value, String... keys)
{
  for (int i = 0, lastIndex = keys.length - 1; i <= lastIndex; i++)
  {
    String key = keys[i];
    Object v = ymlMap.get(key);
    if (v == null) // Assumed value is never null, if key exists
      throw new /* KeyNotFound */ RuntimeException("Key '" + key + "' not found");
    if (i < lastIndex)
      ymlMap = (Map<String, Object>) v;
    else
      ((Map<String, String>) ymlMap).put(key, value);
  }
}
票数 0
EN

Stack Overflow用户

发布于 2018-03-14 18:19:10

您可以通过一个for循环来完成这个任务,请参见下面的示例:

代码语言:javascript
复制
private static void updateYmlContent(Map<String, Object> map, String newValue, String... keys) {
    for (int i = 0; i < keys.length; i++) {
        if (i + 1 == keys.length) {
            map.put(keys[i], newValue);
            return;
        }
        if (map.get(keys[i]) instanceof Map) {
            map = (Map<String, Object>) map.get(keys[i]);
        } else {
            throw new RuntimeException();
        }
    }
    throw new RuntimeException();
}

还请看看它是如何使用的:

代码语言:javascript
复制
public static void  main(String[] keys) throws Exception {
    Map<String, Object> ymlMap = new HashMap<>();

    Map<Object, Object> nested1 = new HashMap<>();
    Map<Object, Object> nested2 = new HashMap<>();

    nested2.put("key3", "oldvalue1");
    nested2.put("key4", "oldvalue2");
    nested1.put("key2", nested2);
    ymlMap.put("key1", nested1);

    updateYmlContent(ymlMap, "new", "key1", "key2", "key3");

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49282538

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档