首页 文章

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

提问于
浏览
0

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

  • KEY1:
  • key2:value1

  • KEY3:

  • key4:value2

  • key5:value3

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

这是我更新值的代码,它正在运行。 但是,这只是通过嵌套映射迭代两次,我需要它根据需要迭代它

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]);
    }
}

3 回答

  • 0

    使用递归和深度计数器来遍历地图的每个级别。我没有编译这个,所以它可能需要一些调整,但这是基本的想法:

    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

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

    @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

    您可以通过一个for循环来完成,请参阅示例:

    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();
    }
    

    另外请看它是如何使用的:

    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");
    
    }
    

相关问题