简体   繁体   English

如何从LinkedHashMap中删除空值 <String,Object> 嵌套对象具有空值

[英]How do I remove null values from LinkedHashMap<String,Object> with nested objects having null values

My JSON Doc is structured like this and being saved in MongoDB with null values. 我的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
}

I have also tried to put @JsonInclude(JsonInclude.Include.NON_NULL) 我也尝试过将@JsonInclude(JsonInclude.Include.NON_NULL)

My Hash map is declared like 我的哈希图声明为

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

As far as I can tell this should be removing all null values regardless of level/layer in the Map. 据我所知,这应该删除所有null值,而不管Map中的级别/图层如何。

JSON is stored like this 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
}

Should be stored like this 应该这样存放

{
"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
}

The problem is that you are removing null values from the top level Map. 问题是您正在从顶级Map中删除空值。

This map contains internally values that are other maps. 该映射包含其他映射的内部值。 You don't remove null values from thos maps. 您不会从thos映射中删除空值。

Try to use a recursive function to remove all null elements from inner maps. 尝试使用递归函数从内部映射中删除所有空元素。

The json: json:

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

} }

is equivalent to the following maps in java 等效于java中的以下映射

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

If you apply the code to remove null values to map: 如果应用代码以删除要映射的空值:

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

results in a map that is equivalent to the following manually built map: 会产生与以下手动生成的地图等效的地图:

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

because it removes null values from the map, not from innerMap. 因为它会从地图而不是innerMap中删除空值。

You can remove all null elements at any level as follow: 您可以按以下步骤删除所有级别的所有null元素:

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

And you can remove all null items as follow: 您可以按照以下步骤删除所有空项目:

Map map = ...
removeNull(map); 

As mentioned by others, you would need to do it in a recursive manner. 正如其他人提到的那样,您将需要以递归方式进行操作。 For example, if you have function like removeNulls : 例如,如果您具有类似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;
}

Then, you could do it like: 然后,您可以这样做:

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

This is just to serve as an example. 这仅是作为示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM