使用 LinkedTreeMap 从 Json 字符串中删除键值对(嵌套在任何级别)
Remove the key-value pairs (nested at any level) from a Json String using LinkedTreeMap
我有一个 Json String
表示一个对象,该对象还有另一个嵌套对象。另外,我有一个键列表,我需要从 Json String
中删除这些键。这些键可以位于此字符串内的任何嵌套对象级别。最后,我需要将这个编辑后的 Json 字符串与另一个字符串进行比较并输出差异。我需要从第一个 Json 字符串中删除那些键值对,因为我需要在比较过程中忽略这些键。目前,我正在将 Json 字符串转换为 Gson API
提供的 LinkedTreeMap
,然后进行 Map.difference()
比较。请提出解决方案。
我通过在 Nested LinkedTreeMap 中递归遍历直到找到该字段并将其删除(如果存在)来完成此操作。需要提供 Key
的完整路径以获取对象内的确切键值位置(如下面 Json 示例中的 "objects.desc"从 Json 字符串中删除 desc)
Json 样本:
{
"message": "MSG",
"code": "COD001",
"objects": [
{
"resource": "Student",
"field": "StudentId",
"desc": "Student Description"
}
]
}
代码示例:
public MapDifference<String, Object> getMapDifference(String jsonString1, String jsonString2) {
MapDifference<String, Object> mapDifference = null;
Gson gson = new Gson();
Type mapType = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> firstMap = gson.fromJson(jsonString1, mapType);
Map<String, Object> secondMap = gson.fromJson(jsonString2, mapType);
firstMap = CollectionUtils.isEmpty(firstMap) ? new HashMap<>() : firstMap;
secondMap = CollectionUtils.isEmpty(secondMap) ? new HashMap<>() : secondMap;
//This contains the List of keys that is required to be filtered out from Json Strings before comparision like {"message", "objects.desc"}
List<String> firstIgnoreList = getIgnoreList1();
List<String> secondIgnoreList = getIgnoreList2();
filterKeys(firstMap, firstIgnoreList);
filterKeys(secondMap, secondIgnoreList);
mapDifference = Maps.difference(firstMap, secondMap);
return mapDifference;
}
private void filterKeys(Map<String, Object> keyMap, List<String> ignoreList) {
if (!(CollectionUtils.isEmpty(keyMap) || CollectionUtils.isEmpty(ignoreList))) {
ignoreList.stream().parallel().forEach(key -> recursiveRemove(keyMap, key));
}
}
private static void recursiveRemove(Map<String, Object> keyMap, String key) {
List<String> path = Arrays.asList(StringUtils.split(key.trim(), "."));
int size = path.size();
int index = 0;
List<LinkedTreeMap> treeMapList = new ArrayList<LinkedTreeMap>();
treeMapList.add((LinkedTreeMap) keyMap);
while (index != size - 1) {
int i = index++;
List<LinkedTreeMap> treeMapListTemp = new ArrayList<LinkedTreeMap>();
treeMapList.stream().parallel().forEach(treeMap -> {
Object obj = treeMap.get(path.get(i));
if (obj instanceof List) {
treeMapListTemp.addAll((List<LinkedTreeMap>) obj);
} else if (obj instanceof LinkedTreeMap) {
treeMapListTemp.add((LinkedTreeMap) obj);
}
});
treeMapList = treeMapListTemp;
}
treeMapList.stream().parallel().forEach(treeMap -> treeMap.remove(path.get(size - 1)));
}
我有一个 Json String
表示一个对象,该对象还有另一个嵌套对象。另外,我有一个键列表,我需要从 Json String
中删除这些键。这些键可以位于此字符串内的任何嵌套对象级别。最后,我需要将这个编辑后的 Json 字符串与另一个字符串进行比较并输出差异。我需要从第一个 Json 字符串中删除那些键值对,因为我需要在比较过程中忽略这些键。目前,我正在将 Json 字符串转换为 Gson API
提供的 LinkedTreeMap
,然后进行 Map.difference()
比较。请提出解决方案。
我通过在 Nested LinkedTreeMap 中递归遍历直到找到该字段并将其删除(如果存在)来完成此操作。需要提供 Key
的完整路径以获取对象内的确切键值位置(如下面 Json 示例中的 "objects.desc"从 Json 字符串中删除 desc)
Json 样本:
{
"message": "MSG",
"code": "COD001",
"objects": [
{
"resource": "Student",
"field": "StudentId",
"desc": "Student Description"
}
]
}
代码示例:
public MapDifference<String, Object> getMapDifference(String jsonString1, String jsonString2) {
MapDifference<String, Object> mapDifference = null;
Gson gson = new Gson();
Type mapType = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> firstMap = gson.fromJson(jsonString1, mapType);
Map<String, Object> secondMap = gson.fromJson(jsonString2, mapType);
firstMap = CollectionUtils.isEmpty(firstMap) ? new HashMap<>() : firstMap;
secondMap = CollectionUtils.isEmpty(secondMap) ? new HashMap<>() : secondMap;
//This contains the List of keys that is required to be filtered out from Json Strings before comparision like {"message", "objects.desc"}
List<String> firstIgnoreList = getIgnoreList1();
List<String> secondIgnoreList = getIgnoreList2();
filterKeys(firstMap, firstIgnoreList);
filterKeys(secondMap, secondIgnoreList);
mapDifference = Maps.difference(firstMap, secondMap);
return mapDifference;
}
private void filterKeys(Map<String, Object> keyMap, List<String> ignoreList) {
if (!(CollectionUtils.isEmpty(keyMap) || CollectionUtils.isEmpty(ignoreList))) {
ignoreList.stream().parallel().forEach(key -> recursiveRemove(keyMap, key));
}
}
private static void recursiveRemove(Map<String, Object> keyMap, String key) {
List<String> path = Arrays.asList(StringUtils.split(key.trim(), "."));
int size = path.size();
int index = 0;
List<LinkedTreeMap> treeMapList = new ArrayList<LinkedTreeMap>();
treeMapList.add((LinkedTreeMap) keyMap);
while (index != size - 1) {
int i = index++;
List<LinkedTreeMap> treeMapListTemp = new ArrayList<LinkedTreeMap>();
treeMapList.stream().parallel().forEach(treeMap -> {
Object obj = treeMap.get(path.get(i));
if (obj instanceof List) {
treeMapListTemp.addAll((List<LinkedTreeMap>) obj);
} else if (obj instanceof LinkedTreeMap) {
treeMapListTemp.add((LinkedTreeMap) obj);
}
});
treeMapList = treeMapListTemp;
}
treeMapList.stream().parallel().forEach(treeMap -> treeMap.remove(path.get(size - 1)));
}