【问题标题】:How to replace keys in a map based on mapping如何根据映射替换映射中的键
【发布时间】:2020-08-23 02:55:08
【问题描述】:

我有一个从某个外部系统获取的 JSON。我需要根据我的系统映射将该 JSON 转换为键值。例如:

来自外部系统的 JSON:

   [{
        "name": "Tim",
        "address": "New York",
        "education" : {
             "university": "XYZ"     
          }
    },
    {
        "name": "Steve",
        "address": "UK"
    }]

我有以下我们需要使用的映射:

{
"name": "firstName",
"address": "location",
"university": "college"
}

即要映射到 firstName 的名称和要映射到位置的地址。最后,我处理后的映射将如下所示:

       [{
            "firstName": "Tim",
            "location": "New York"
            "education" : {
             "college": "XYZ"     
             }
        },
        {
            "firstName": "Steve",
            "location": "UK"
        }]

实现这一目标的最佳方法是什么?我应该使用普通的 hashmap 操作还是有其他有效的方法。为此,我正在检查 JSONNode,但该方法类似于哈希映射。有没有什么实用程序可以用来遍历像 json map 这样的树并替换密钥?

【问题讨论】:

    标签: java json hashmap java-stream jsonnode


    【解决方案1】:

    我是 Jackson 的粉丝,你可以用它来遍历 JSON。当您这样做时,填充一个映射列表,使用您的系统映射替换遇到的具有映射的任何键,而其他键保持不变。最后,将地图列表转储为 JSON。

    编辑:在下面添加代码示例

    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.node.ArrayNode;
    
    import java.io.IOException;
    import java.util.*;
    
    public class ReplaceKeys {
        private static final ObjectMapper mapper = new ObjectMapper();
    
        private static Map<String, String> keymap;
        static {
            try {
                // Create the key map based on the json provided by OP
                keymap = mapper.readValue("{\n" +
                        "\"name\": \"firstName\",\n" +
                        "\"address\": \"location\",\n" +
                        "\"university\": \"college\"\n" +
                        "}", Map.class);
            } catch (IOException e) {
                System.out.println("whoops");
            }
        }
    
        public static String mapKeys(String input) throws IOException {
            // Assume the input is an array and therefore so is the output.
            List<Map<String, Object>> output = new ArrayList<>();
            ArrayNode inputArray = (ArrayNode) mapper.readTree(input);
            for (JsonNode node : inputArray) {
                output.add(mapKeys(node));
            }
            return mapper.writeValueAsString(output);
        }
    
        private static Map<String, Object> mapKeys(JsonNode node) {
            Map<String, Object> map = new HashMap<>();
            for (Iterator<String> iterator = node.fieldNames(); iterator.hasNext(); ) {
                String key = iterator.next();
                key = keymap.containsKey(key) ? keymap.get(key) : key;
                for (JsonNode child : node) {
                    if (node.isValueNode()) {
                        // This is coercing everything to a String. You could dig into using
                        // proper types based on node.getNodeType().
                        map.put(key, node.asText());
                    } else {
                        map.put(key, mapKeys(child));
                    }
                }
            }
            return map;
        }
    }
    
    

    【讨论】:

    • 你能举个例子吗?
    • 添加了一个示例 - 尚未运行/测试它,但这是我的想法。希望对您有所帮助。
    • @codeluv 这有帮助吗?如果是这样,我将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2021-03-20
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多