如何使用嵌套的对象具有null值从LinkedHashMap <string,object>中删除null值

时间:2019-05-07 14:45:35

标签: java json hashmap

我的JSON文档的结构如下,并以空值保存在MongoDB中。

{
"userId": "123456",
"session": "string",
"timestamp": 0,
"product": "tracker",
"version": "13",
"flight": "A",
"activity": "search",
"action": "opportunity",
"dataDictionary": {
    "datadictionary": {
        "query": "roofing",
        "docid": 12,
        "rank": 1,
        "search": {
            "id": null
        }
    },
    "id": 40
}

我也尝试过放@JsonInclude(JsonInclude.Include.NON_NULL)

我的哈希映射声明为

Map<String, Object >dataDict = new LinkedHashMap<>();
dataDict.values().removeIf(Objects::isNull);

据我所知,应该删除所有空值,而不管地图中的级别/层。

JSON这样存储

{

"userId": "123456",
"session": "string",
"timestamp": 0,
"product": "tracker",
"version": "13",
"flight": "A",
"activity": "search",
"action": "opportunity",
"dataDictionary": {
    "datadictionary": {
        "query": "roofing",
        "docid": 12,
        "rank": 1,
        "search": {
            "id": null,
            "name":"test"
        }
    },
    "id": 40
}

应该这样存储

{
"userId": "123456",
"session": "string",
"timestamp": 0,
"product": "tracker",
"version": "13",
"flight": "A",
"activity": "search",
"action": "opportunity",
"dataDictionary": {
    "datadictionary": {
        "query": "roofing",
        "docid": 12,
        "rank": 1,
        "search": {
            "name":"test"
        }
    },
    "id": 40
}

2 个答案:

答案 0 :(得分:2)

问题是您正在从顶级Map中删除空值。

此映射在内部包含其他映射的值。您不会从thos映射中删除空值。

尝试使用递归函数从内部映射中删除所有空元素。

json:

{
   "topField": null,
   "innerMap": {
      "innerField": null
   }

}

等效于Java中的以下映射

Map map = new LinkedHashMap();
map.put("topField", null);
Map innerMap = new LinkedHashMap();
innerMap.put("innerField", null);
map.put("innerMap", innerMap);

如果您应用代码删除要映射的空值:

map.values().removeIf(Objects::isNull);

生成的地图等效于以下手动构建的地图:

Map map = new LinkedHashMap();
// map.put("topField", null);
Map innerMap = new LinkedHashMap();
innerMap.put("innerField", null);
map.put("innerMap", innerMap);

因为它从地图而不是innerMap中删除空值。

您可以按以下任意级别删除所有空元素:

public void removeNull(Map map) {
   map.values().removeIf(Objects::isNull);
   for (Object value: map.values()) {
       if (value instanceof Map) {
         // Apply a recursion on inner maps
         removeNull((Map) value);
       }
   }
} 

您可以按照以下步骤删除所有空项目:

Map map = ...
removeNull(map); 

答案 1 :(得分:0)

正如其他人所提到的,您将需要以递归方式进行操作。例如,如果您具有类似removeNulls的功能:

private boolean removeNulls(final Object o) {
    if (Objects.isNull(o)) {
        return true;
    } else if (o instanceof Map) {
        ((Map) o).values().removeIf(MyClass::removeNulls);
    }
    return false;
}

然后,您可以这样做:

dataDict.values().removeIf(MyClass::removeNulls);

这只是一个例子。