Как удалить нулевые значения из LinkedHashMapс вложенными объектами, имеющими нулевые значения - PullRequest
0 голосов
/ 07 мая 2019

Мой JSON Doc имеет такую ​​структуру и сохраняется в 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 ]

2 голосов
/ 07 мая 2019

Проблема в том, что вы удаляете нулевые значения с карты верхнего уровня.

Эта карта содержит внутренние значения, которые являются другими картами. Вы не удаляете нулевые значения из этих карт.

Попробуйте использовать рекурсивную функцию для удаления всех нулевых элементов из внутренних карт.

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); 
0 голосов
/ 07 мая 2019

Как уже упоминалось, вам придется делать это рекурсивно.Например, если у вас есть такая функция, как 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);

Это просто для примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...