【问题标题】:Manually remove TreeMap nested null values手动删除 TreeMap 嵌套的空值
【发布时间】:2021-09-20 13:59:41
【问题描述】:

我正在编写一种从 json (LinkedTreeMap) 中手动删除空值的方法。

    private static Gson gson = new Gson();

    public static LinkedTreeMap removeNullJsonObjects(Object object) {

        JsonElement jsonElement = gson.toJsonTree(object);
        LinkedTreeMap<Object, Object> linkedTreeMap = gson.fromJson(jsonElement, LinkedTreeMap.class);
        
        for (var entry : linkedTreeMap.entrySet()) {

            Object value = entry.getValue();
            if (value == null) {
                linkedTreeMap.remove(entry.getKey());
            } else if (value instanceof LinkedTreeMap<?, ?>) {
                removeNullJsonObjects(value);
                // here I need to loop again and save somehow result before ??
            }
        }

        return linkedTreeMap;
    }

但问题是json的深度可以是0...n。这意味着我应该循环N次并存储它,我不知道如何为其编写代码。

所以我可以拥有任何深度的 json,例如:像这样:

{
    "technicalData": {
        "attributesList": {
            "attributes": [{
                    "attribute": {
                        "code": "LocalModelName",
                        "description": {
                            "value": "Boer"
                        }
                    }
                }, {
                    "attribute": {
                        "code": "C303"
                    }
                }
            ]
        }
    },
    "modelGroups": {
        "modelGroup": [{}
        ]
    }
}

【问题讨论】:

    标签: java json gson treemap


    【解决方案1】:

    你的实现中的一些问题:

    1. linkedTreeMap.remove 内部 for 循环可能会导致 ConcurrentModificationException
    2. 当值为List时,还要检查其元素是否为Map,并相应地移除空值条目。
    3. remove逻辑应该被提取到一个方法中,不需要再把Map转换成JsonElement

    以下代码在 Java 16 上运行。

    import com.google.gson.Gson;
    import com.google.gson.JsonElement;
    import com.google.gson.internal.LinkedTreeMap;
    
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    public class RemoveNull {
    
        private static Gson gson = new Gson();
        private static String json =
                """
                        {
                            "technicalData": {
                                "attributesListNull": null,
                                "attributesList": {
                                    "attributes": [{
                                            "attributeNull": null,
                                            "attribute": {
                                                "code": "LocalModelName",
                                                "description": {
                                                    "value": "Boer",
                                                    "valueNull": null
                                                }
                                            }
                                        }, {
                                            "attribute": {
                                                "code": "C303",
                                                "codeNull": null
                                            }
                                        }
                                    ]
                                }
                            },
                            "modelGroups": {
                                "modelGroup": [{}],
                                "modelGroupNull": null
                            }
                        }
                        """;
    
        public static void main(String[] args) {
            JsonElement jsonElement = gson.fromJson(json, JsonElement.class);
            LinkedTreeMap<Object, Object> linkedTreeMap = gson.fromJson(jsonElement, LinkedTreeMap.class);
            System.out.println("Before remove:" + linkedTreeMap);
            removeNullMapping(linkedTreeMap);
            System.out.println("After remove:" + linkedTreeMap);
        }
    
        // Recursively remove null value mapping of input map, values of input map
        // and element in list values of input map
        private static void removeNullMapping(Map<Object, Object> map) {
            Iterator<Map.Entry<Object, Object>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                var entry = iterator.next();
                Object value = entry.getValue();
                if (value == null) {
                    iterator.remove();
                } else if (value instanceof Map) {
                    removeNullMapping((Map<Object, Object>) value);
                } else if (value instanceof List) {
                    for (Object o : (List<Object>) value) {
                        if (o instanceof Map) {
                            removeNullMapping((Map<Object, Object>) o);
                        }
                    }
                }
            }
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 2016-11-06
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 2019-04-25
      • 2015-07-13
      • 1970-01-01
      相关资源
      最近更新 更多