我试图比较两个动态json数据,如果它们不相等,那么我打印差异。为此,我正在使用
Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Map<String,Object> firstMap = g.fromJson(jsonElement1, mapType);
Map<String, Object> secondMap = g.fromJson(jsonElement2, mapType);
System.out.println(Maps.difference(firstMap, secondMap));
我需要在控制台中显示差异。 这是我试图显示json
的差异的java代码 public class Tester {
public static ArrayList<Object> ls1 = new ArrayList<Object>();
public static ArrayList<Object> ls2 = new ArrayList<Object>();
public static void main(String[] args) throws Exception {
JsonParser parser = new JsonParser();
try{
Gson g = new Gson();
JsonElement jsonElement1 = parser
.parse(new FileReader("D:\\file1.json"));
JsonElement jsonElement2 = parser
.parse(new FileReader("D:\\file2.json"));
System.out.println("Is the two JSON File Same: "+compareJson(jsonElement1, jsonElement2));
if(!compareJson(jsonElement1, jsonElement2)){
Type mapType = new TypeToken<Map<String, Object>>(){}.getType();
Map<String,Object> firstMap = g.fromJson(jsonElement1, mapType);
Map<String, Object> secondMap = g.fromJson(jsonElement2, mapType);
System.out.println(Maps.difference(firstMap, secondMap));
}
else{
System.out.println("The Two JSON Are SAME!!!!!!!!!!!!!!!");
}
}catch(Exception e1){
e1.printStackTrace();
}
}
public static boolean compareJson(JsonElement json1, JsonElement json2) {
boolean isEqual = true;
// Check whether both jsonElement are not null
if (json1 != null && json2 != null) {
// Check whether both jsonElement are objects
if (json1.isJsonObject() && json2.isJsonObject()) {
Set<Entry<String, JsonElement>> ens1 = ((JsonObject) json1).entrySet();
Set<Entry<String, JsonElement>> ens2 = ((JsonObject) json2).entrySet();
JsonObject json2obj = (JsonObject) json2;
if (ens1 != null && ens2 != null && (ens2.size() == ens1.size())) {
// Iterate JSON Elements with Key values
for (Entry<String, JsonElement> en : ens1) {
isEqual = isEqual && compareJson(en.getValue(),json2obj.get(en.getKey()));
}
} else {
return false;
}
}
// Check whether both jsonElement are arrays
else if (json1.isJsonArray() && json2.isJsonArray()) {
JsonArray jarr1 = json1.getAsJsonArray();
JsonArray jarr2 = json2.getAsJsonArray();
if (jarr1.size() != jarr2.size()) {
return false;
} else {
int i = 0;
// Iterate JSON Array to JSON Elements
for (JsonElement je : jarr1) {
isEqual = isEqual && compareJson(je, jarr2.get(i));
i++;
}
if (isEqual) {
Object[] o1 = ls1.toArray();
Object[] o2 = ls2.toArray();
isEqual = Arrays.deepEquals(o1, o2);
}
}
}
// Check whether both jsonElement are null
else if (json1.isJsonNull() && json2.isJsonNull()) {
return true;
}
// Check whether both jsonElement are primitives
else if (json1.isJsonPrimitive() && json2.isJsonPrimitive()) {
ls1.add(json1);
ls2.add(json2);
}
} else if (json1 == null && json2 == null) {
return true;
} else {
return false;
}
return isEqual;
}
}
对象数组
if (isEqual) {
Object[] o1 = ls1.toArray();
Object[] o2 = ls2.toArray();
isEqual = Arrays.deepEquals(o1, o2);
}
对象数组o1和o2为null不知道为什么它为null。
这两个示例json我用于测试json1 {"Company List":["Compnay: Paypal","Compnay: eBay","Compnay: Google"]}
json2 {"Company List":["Compnay: Viswesh","Compnay: Anand","Compnay: Anand"]}
在json中公司的值是不同的,所以代码必须返回false但代码返回true
答案 0 :(得分:0)
评论部分太长了,所以这里是一个答案:
首先,如果您的Json对象具有不同的结构,您仍然会遇到问题。例如:
{"Company List":["Compnay: eBay","Compnay: Google","Compnay: Paypal"]}
{"Company List":"ImAString"}
两者都不是null,它是一个原语和一个数组。你没有抓住这种情况,所以你的isEqual将保持正确。
无论如何,回到手头的问题。
在你的情况下,不应该对数组进行相同的排序。
if (isEqual) {
Object[] o1 = ls1.toArray();
Object[] o2 = ls2.toArray();
isEqual = Arrays.deepEquals(o1, o2);
}
您可以通过将其更改为:
来轻松解决此问题if (isEqual) {
isEqual = ls1.containsAll(ls2);
}
虽然我应该提到我发现你的ls1和ls2都是静态的并且只是不断获取条目真的很奇怪。在你的例子中它并不重要,因为它们太小了,但是对于大文件,你会得到巨大的ArrayLists,其中有很多值出现多次。
每次到JsonArray时都要比较它们,这似乎是浪费时间。
由于这仍然存在无法将不同排序的JSON数组与不是基元的JSON元素进行比较的问题,这里是比较两个数组的强力方法。请记住,它远非一种最佳方法,但实施起来相对容易:
public static boolean equality(ArrayList<Object> list1, ArrayList<Object> list2) {
if (list1.length != list2.length) return false;
for (Object entry1 : list1) {
Object equalEntry = null;
for(Object entry2 : list2) {
if (entry1.equals(entry2)) {
equalEntry = entry2;
break;
}
}
if (equalEntry == null) return false;
list2.remove(equalEntry);
}
return true;
}
我还应该提到它显然不像if (entry1.equals(entry2))
那么简单。您可能必须在此时进行递归并调用您的比较方法。此外,我非常确定您的列表包含JSON元素而不是对象;)