gson 手动删除TreeMap嵌套空值

zsohkypk  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(187)

我正在编写一个方法来手动删除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": [{}
        ]
    }
}
fsi0uk1n

fsi0uk1n1#

您在实施中遇到的一些问题:

  1. for循环内的linkedTreeMap.remove可能导致ConcurrentModificationException
    1.当值为List时,我们还应该检查其元素是否为Map,并相应地删除空值条目。
    1.移除逻辑应提取到方法中,无需再次将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);
                    }
                }
            }
        }
    }
}

相关问题