废话少说,直接入题。

在面向对象语言中,经常会比较两个对象是否相等,而比较的大多是实体类实例,也就是封装数据的那些类实例,或者是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;
}

比较任意两个JSON串是否相等(比较对象是否相等)JAVA版的更多相关文章

  1. 9-2、大型项目的接口自动化实践记录----递归判断两个json串是否相等

    1.已知json串构成的情况下判断 先构造一下场景,假设已经把各个数据都移除掉不对比的字段 图1 预期.实际结果,复杂接口返回多层嵌套json时,同下 图2 预期.实际结果值为:{child_json ...

  2. 类对象序列化为json串,json串反序列化为类对象

    1.类对象序列化为json串: 方法一: class P(object): def __init__(self,name,age,sex): self.name=name self.age=age s ...

  3. python实现比对两个json串的方法

    记录瞬间 前段时间为了解决一些实际问题,引出了要对json字符串进行比对的需求. 觉得有意义,作以简单记录. # 比对数据 def compare_data(set_key, src_data, ds ...

  4. [原创] C# dynamic拼接Json串

    using Newtonsoft.Json; 之前拼接两个json串,是用的这样的代码 , json1.Length - ); json2 = json2.Insert(json2 - , tmp); ...

  5. Java开发笔记(一百零八)JSON串的定义和解析

    前面提到URL尾巴支持添加请求参数,具体格式形如“参数A名称=A参数值&参数B名称=B参数值”,可是这种格式只能传递简单的键值对信息,不能传递结构化数据,也无法传递数组形式的参数,因而它不适用 ...

  6. 用Newtonsoft将json串转为对象的方法(详解)

    首先,将json串转为一个JObject对象: JObject jo = (JObject)JsonConvert.DeserializeObject(CurrentSelectedItemReq) ...

  7. Json串的字段如果和类中字段不一致,如何映射、转换?

    Json串是我们现在经常会遇到的一种描述对象的字符串格式.在用Java语言开发的功能中,也经常需要做Json串与Java对象之间的转换. fastjson就是经常用来做Json串与Java对象之间的转 ...

  8. [MVC_Json序列化]Json字符串反序列化成C#对象

    上一篇中有Json序列化相关问题得到了解决. 那么结果集为Json串时,如何将Json串转成C#对象呢? 现举例说明: -现有如下字符串数据 string k = "{\"ring ...

  9. spring入门(七)【springMVC返回json串】

    现在多数的应用为了提高交互性多使用异步刷新,即在不刷新整个页面的情况下,只刷新局部,局部刷新用得最多就是ajax,ajax和后台进行交互的数据格式使用的最多的是JSON,这里简单描述,在springm ...

随机推荐

  1. Linux启动/停止/重启Mysql数据库的方法——转载

    Mysql启动.停止.重启常用命令 a.启动方式1.使用 service 启动:[root@localhost /]# service mysqld start (5.0版本是mysqld)[root ...

  2. laravel 数据库迁移

    问题:之前有创建迁移文件 并且执行过 如果删除迁移文件 再重新创建迁移文件时就有问题 提示找不到之前的迁移文件 /** 一开始执行的命令 php artisan make:migration crea ...

  3. Prim算法和Kruskal算法(图论中的最小生成树算法)

    最小生成树在一个图中可以有多个,但是如果一个图中边的权值互不相同的话,那么最小生成树只可能存在一个,用反证法很容易就证明出来了. 当然最小生成树也是一个图中包含所有节点的权值和最低的子图. 在一个图中 ...

  4. DUILIB CDialogBuilder 使用问题

    频繁调用CDialogBuilder的create接口创建同一个配置文件,会报异常: 正常的处理方式如下: if (!m_dlgBuilder.GetMarkup()->IsValid()) { ...

  5. [转]Excel 取汉字拼音首位

    转自:http://jingyan.baidu.com/article/63acb44adca44461fcc17e85.html 转自:http://jingyan.baidu.com/articl ...

  6. 技术英文单词贴--E

    E element 元素,成分,要素 expire 到期,终止,期满

  7. jvm中加载类的全过程

    ClassLoader的作用:概括来说就是将编译后的class装载.加载到机器内存中,为了以后的程序的执行提供前提条件. jvm的整个生命周期,如下图所示 加载=>验证=>准备=>解 ...

  8. PostGreSQL存储过程

    1 返回结果集的存储过程 -- drop FUNCTION getall();CREATE or REPLACE FUNCTION getall() RETURNS SETOF users  AS$B ...

  9. 第三章 深入 ZAB 协议

    上一节介绍了ZAB协议的内容,本节将从系统模型.问题描述.算法描述和运行分析四方面来深入了解 ZAB 协议. 系统模型 在一个由一组进程 n ={P1,P2,...Pn}组成的分布式系统中,每一个进程 ...

  10. asp.net MVC 源码分析

    先上一张图吧 asp.net请求机制的图  by传智播客邹华栋老师 然后是 邹老师添加MVC请求过程的图 其实MVC 是在.netframework上加了一个过滤器  HttpModule 在C:\W ...