#java
#java
Вопрос:
Дано два объекта json
String a1 = "{"a":[{"b":"1"}, {"b":"2"}]}";
String a2 = "{"a":[{"b":"2"}, {"b":"1"}]}";
Я хотел бы сравнить их независимо от порядка объектов в массиве. Я использую Jackson
, но это не работает.
ObjectMapper om = new ObjectMapper().configure(
SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true
);
Map<String, Object> m1 = (Map<String, Object>)(om.readValue(a1, Map.class));
Map<String, Object> m2 = (Map<String, Object>)(om.readValue(a2, Map.class));
System.out.println(m1.equals(m2));
Есть ли какой-нибудь удобный способ их правильного сравнения?
Комментарии:
1. Они не равны.
2. почему вы считаете, что эти объекты равны?
3. Моя ошибка. Я бы скорее сказал, сравнивая их независимо от порядка объектов в массиве.
Ответ №1:
Ваш om.readValue()
вызов возвращает Map<String, List<Map<String, Integer>>>
:
Map<String, List<Map<String, Integer>>> m1 = om.readValue(a1, Map.class);
Map<String, List<Map<String, Integer>>> m2 = om.readValue(a2, Map.class);
System.out.println(m1); //{a=[{b=1}, {b=2}]}
System.out.println(m2); //{a=[{b=2}, {b=1}]}
Списки {b=1}, {b=2}
и {b=2}, {b=1}
не равны из-за их порядка.
Итак, я преобразовал список в HashSet, а затем запустил сравнение:
Map<String, HashSet<Map<String, Integer>>> m1Collected = m1.entrySet().stream()
.map(e -> Map.entry(e.getKey(), new HashSet<>(e.getValue())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map<String, HashSet<Map<String, Integer>>> m2Collected = m2.entrySet().stream()
.map(e -> Map.entry(e.getKey(), new HashSet<>(e.getValue())))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(m1Collected.equals(m2Collected)); //prints true
Вы также можете использовать JSONassert со строгим режимом, установленным в false, для сравнения JSON-файлов, игнорируя порядок.
Комментарии:
1. но тогда вы модифицируете объект перед его сравнением. Это все равно, что сказать
"foo" == "ofo"
2. @njzk2 если бы OP хотел сравнить порядок, они бы не опубликовали вопрос