比较任意两个JSON串是否相等(比较对象是否相等)JAVA版
2014-07-24 17:33
513 查看
废话少说,直接入题。
在面向对象语言中,经常会比较两个对象是否相等,而比较的大多是实体类实例,也就是封装数据的那些类实例,或者是Map、List互相嵌套成的复杂数据结构。
比较对象是否相等,常见的思路是重写equals方法,但鉴于对象的种类多变,嵌套层次复杂,仅仅靠重写equals是很难实现的。
小菜的思路是可以把对象序列化,由于这些对象均是用来表达数据结构,因此可以直接转换成JSON字符串,用字符串来描述数据结构,避免实现Serializable接口。将对象序列化成字符串后,比较是否相等就相对简单了。
小菜提供的正是比较两个JSON串是否相等的方法,并不是说JSON串完全一样才叫相等,对于List(或数组)结构而言,如果仅仅是元素排列顺序不同,也是相等的。
为了保证方法的准确性,请传入标准的JSON串,也就是说key也要加双引号。用过js的童鞋可能会被误导:我在js中写的JSON,key可以不加双引号啊!实际上,你在js中写的是js语言的Object,并不是JSON,只不过它的语法和JSON非常像而已,JSON仅仅是一种字符串规范,而且真正的JSON只有一种,那就是key加了双引号的!
另外,此方法不依赖任何第三方包。
最后声明,由于数据结构复杂,小菜对这个方法不可能进行遍历性测试,所以这个方法的准确性有待考究,请谨慎使用!如有问题,欢迎反馈!
View Code
在面向对象语言中,经常会比较两个对象是否相等,而比较的大多是实体类实例,也就是封装数据的那些类实例,或者是Map、List互相嵌套成的复杂数据结构。
比较对象是否相等,常见的思路是重写equals方法,但鉴于对象的种类多变,嵌套层次复杂,仅仅靠重写equals是很难实现的。
小菜的思路是可以把对象序列化,由于这些对象均是用来表达数据结构,因此可以直接转换成JSON字符串,用字符串来描述数据结构,避免实现Serializable接口。将对象序列化成字符串后,比较是否相等就相对简单了。
小菜提供的正是比较两个JSON串是否相等的方法,并不是说JSON串完全一样才叫相等,对于List(或数组)结构而言,如果仅仅是元素排列顺序不同,也是相等的。
为了保证方法的准确性,请传入标准的JSON串,也就是说key也要加双引号。用过js的童鞋可能会被误导:我在js中写的JSON,key可以不加双引号啊!实际上,你在js中写的是js语言的Object,并不是JSON,只不过它的语法和JSON非常像而已,JSON仅仅是一种字符串规范,而且真正的JSON只有一种,那就是key加了双引号的!
另外,此方法不依赖任何第三方包。
最后声明,由于数据结构复杂,小菜对这个方法不可能进行遍历性测试,所以这个方法的准确性有待考究,请谨慎使用!如有问题,欢迎反馈!
import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 比较两个json串是否相同 * @param j1 第一个json串(json串中不能有换行) * @param j2 第二个json串(json串中不能有换行) * @return 布尔型比较结果 */ public static boolean jsonEquals(String j1,String j2){ //将json中表示list的[]替换成{}。思想:只保留层次结构,不区分类型 //这样直接替换,可能会导致某些value中的符号也被替换,但是不影响结果,因为j1、j2的变化是相对的 j1 = j1.replaceAll("\\[", "{"); j1 = j1.replaceAll("]", "}"); j2 = j2.replaceAll("\\[", "{"); j2 = j2.replaceAll("]", "}"); //将json中,字符串型的value中的{},字符替换掉,防止干扰(并没有去除key中的,因为不可能存在那样的变量名) //未转义regex:(?<=:")(([^"]*\{[^"]*)|([^"]*\}[^"]*)|([^"]*,[^"]*))(?=") Pattern pattern = Pattern.compile("(?<=:\")(([^\"]*\\{[^\"]*)|([^\"]*\\}[^\"]*)|([^\"]*,[^\"]*))(?=\")"); j1 = cleanStr4Special(j1, pattern.matcher(j1)); j2 = cleanStr4Special(j2, pattern.matcher(j2)); //转义字符串value中的空格 //未转义regex:"[^",]*?\s+?[^",]*?" pattern = Pattern.compile("\"[^\",]*?\\s+?[^\",]*?\""); j1 = cleanStr4Space(j1, pattern.matcher(j1)); j2 = cleanStr4Space(j2, pattern.matcher(j2)); //现在可以安全的全局性去掉空格 j1 = j1.replaceAll(" ", ""); j2 = j2.replaceAll(" ", ""); //调用递归方法 return compareAtom(j1,j2); } /** * 比较字符串核心递归方法 * @param j1 * @param j2 * @return */ private static boolean compareAtom(String j1,String j2){ if(!j1.equals("?:\"?\"")){ //取出最深层原子 String a1 = j1.split("\\{",-1)[j1.split("\\{",-1).length-1].split("}",-1)[0]; String a2 = j2.split("\\{",-1)[j2.split("\\{",-1).length-1].split("}",-1)[0]; String j2_ = j2; String a2_ = a2; //转换成原子项 String i1[] = a1.split(","); //在同级原子中寻找相同的原子 while(!a2.startsWith(",") && !a2.endsWith(",") && a2.indexOf(":,")<0 && a2.indexOf(",,")<0 ){ //遍历消除 for(String s : i1){ a2_ = a2_.replace(s,""); } //此时a2_剩下的全是逗号,如果长度正好等于i1的长度-1,说明相等 if(a2_.length() == i1.length-1){ //相等则从j1、j2中消除,消除不能简单的替换,因为其他位置可能有相同的结构,必须从当前位置上消除 int index = 0; index = j1.lastIndexOf("{" + a1 + "}"); j1 = j1.substring(0, index)+j1.substring(index).replace("{" + a1 + "}", "?:\"?\""); index = j2.lastIndexOf("{" + a2 + "}"); j2 = j2.substring(0, index)+j2.substring(index).replace("{" + a2 + "}", "?:\"?\""); //递归 return compareAtom(j1, j2); }else{ //寻找下一个同级原子 j2_ = j2_.replace("{" + a2 + "}", ""); a2 = j2_.split("\\{",-1)[j2_.split("\\{",-1).length-1].split("}",-1)[0]; a2_ = a2; } } return false; }else{ //比较是否相同 return j1.equals(j2); } } /** * json字符串特殊字符清理辅助方法 * @param j 需要清理的json字符串 * @param matcher 正则表达式匹配对象 * @return 净化的json串 */ private static String cleanStr4Special(String j,Matcher matcher){ String group = ""; String groupNew = ""; while(matcher.find()){ group = matcher.group(); groupNew = group.replaceAll("\\{", "A"); groupNew = groupNew.replaceAll("}", "B"); groupNew = groupNew.replaceAll(",", "C"); j = j.replace(group, groupNew); } return j; } /** * json串字符串类型的value中的空格清理辅助方法 * @param j 需要清理的json字符串 * @param matcher 正则表达式匹配对象 * @return 净化的json串 */ private static String cleanStr4Space(String j,Matcher matcher){ String group = ""; String groupNew = ""; while(matcher.find()){ group = matcher.group(); groupNew = group.replaceAll(" ", "S"); j = j.replace(group, groupNew); } return j; }
View Code
相关文章推荐
- Java 比较两个对象是否相等【含字符串,区分与不区分大小写】
- 详解JS 比较两个Json对象的值是否相等的实例
- JS中如何比较两个Json对象是否相等
- 比较两个Json对象是否相等
- 详解JS 比较两个Json对象的值是否相等的实例
- java比较两个对象是否相等的方法
- JS中如何比较两个Json对象是否相等实例代码
- java 比较两个对象是否相等
- 比较两个Json对象是否相等
- 深入java的equals方法,怎么比较两个对象的内容是否相等?对象的内容指的是什么?
- java 反射比较两个类型相同的对象 内部的变量是否相等
- JavaScript比较两个对象是否相等的方法
- 比较两个Image对象是否相等、xib中设置自定义整个cell的高度
- 直接比较两个对象是否相等返回false和List中判断是否包含某个对象的问题
- JavaScript比较两个对象是否相等的方法
- java integer对象判断两个数字是否相等
- toCharArray()方法 和 Java中比较两个字符串是否相等equals方法
- 第2章 Java编程基础——FAQ2.21 ==和equals()都可用于比较两个操作数是否相等, 它们有什么区别吗?
- JavaScript比较两个对象是否相等
- 比较两个对象是否相等