java - 将两个没有值的 json 响应与 Jackson 进行比较
问题描述
是否可以将两个 json 响应与 Jackson lib 忽略所有值进行比较。
所以下面将断言属性和值。
{
"employee":
{
"id": "1212",
"fullName": "John Miles",
"age": 34
}
}
代码:
ObjectMapper mapper = new ObjectMapper();
assertEquals(mapper.readTree(s1), mapper.readTree(s2));
解决方案
快速查找并没有产生任何结果,杰克逊为此功能内置了功能。但是,我们可以为此任务编写自己的检查器来比较两个Map<String, ?>
s,从而返回true
iff:
- 两个s
keySet()
相等Map
- 属于两个s的
keySet()
那些对象的 是相等的instanceof Map
Map
- s的值
Map
在结构上也必须相同(递归调用)
对于分析,我们必须假设如果 aMap
是 another 中的值Map
,则它必须是 a,Map<String, ?>
因为我们的解决方案将使用此假设进行未经检查的强制转换。
有了这个假设,解决方案可能如下所示:
@SuppressWarnings("unhecked")
public static boolean areStructuralEqual(Map<String, ?> left, Map<String, ?> right) {
if (!Objects.equals(left.keySet(), right.keySet())) {
return false;
}
Set<String> leftKeysWithMapValues = extractAllKeysThatMapToMaps(left);
Set<String> rightKeysWithMapValues = extractAllKeysThatMapToMaps(right);
if (!Objects.equals(leftKeysWithMapValues, rightKeysWithMapValues)) {
return false;
}
for (String key : leftKeysWithMapValues) {
if (!areStructuralEqual(
(Map<String, ?>) left.get(key),
(Map<String, ?>) right.get(key))) {
return false;
}
}
return true;
}
private static Set<String> extractAllKeysThatMapToMaps(Map<String, ?> map) {
return map.entrySet().stream()
.filter(e -> e.getValue() instanceof Map)
.map(Entry::getKey)
.collect(Collectors.toUnmodifiableSet());
}
请注意,此解决方案不会验证密钥的类型是否相同。此外,如果一个键的值设置为null
一个Map
,而另一个键不存在Map
,则比较将返回false
。后者可以通过过滤掉值为 的键来修复null
:
@SuppressWarnings("unhecked")
public static boolean areStructuralEqual(Map<String, ?> left, Map<String, ?> right) {
Set<Entry<String, ?>> leftEntriesWithNonNullValues =
extractEntriesWithNonNullValues(left);
Set<Entry<String, ?>> rightEntriesWithNonNullValues =
extractEntriesWithNonNullValues(right);
Set<String> leftKeysWithNonNullValues = leftEntriesWithNonNullValues.stream()
.map(Entry::getKey)
.collect(Collectors.toUnmodifiableSet());
Set<String> rightKeysWithNonNullValues = rightEntriesWithNonNullValues.stream()
.map(Entry::getKey)
.collect(Collectors.toUnmodifiableSet());
if (!Objects.equals(leftKeysWithNonNullValues, rightKeysWithNonNullValues)) {
return false;
}
Set<String> leftKeysWithMapValues =
extractAllKeysThatMapToMaps(leftEntriesWithNonNullValues);
Set<String> rightKeysWithMapValues =
extractAllKeysThatMapToMaps(rightEntriesWithNonNullValues);
if (!Objects.equals(leftKeysWithMapValues, rightKeysWithMapValues)) {
return false;
}
for (String key : leftKeysWithMapValues) {
if (!areStructuralEqual(
(Map<String, ?>) left.get(key),
(Map<String, ?>) right.get(key))) {
return false;
}
}
return true;
}
private static Set<String> extractAllKeysThatMapToMaps(Set<Entry<String, ?>> entrySet) {
return entrySet.stream()
.filter(e -> e.getValue() instanceof Map)
.map(Entry::getKey)
.collect(Collectors.toUnmodifiableSet());
}
private static Set<Entry<String, ?>> extractEntriesWithNonNullValues(Map<String, ?> map) {
return map.entrySet().stream()
.filter(e -> Objects.nonNull(e.getValue()))
.collect(Collectors.toUnmodifiableSet());
}
推荐阅读
- java - JNI 中的 GSettings 信号
- bash - 从文件中删除导致其换行的整行
- java - 修改 JavaFX 定期添加的对象
- powershell - 如何在不单独显式选择文件的情况下选择和移动文件列表
- woocommerce - 下订单时获取有关产品库存变化的相关订单 ID
- excel - 为什么我在请求 JIRA Server API 时有时会收到 401 Unauthorized?
- little-man-computer - 将 n 位二进制转换为以 10 为底的数字
- c++ - 如果不存在 RAW 指针变量,则 C++ 移动构造函数与复制构造函数
- python - powershell python中的进度闪烁
- javascript - Chart.js 基于时间的条形图