废话少说,直接入题。

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

    1.html结构 1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html>   <html lang="en"> <head> ...

  2. CentOS使用virtualenv搭建独立的Python环境-python虚拟环境

    CentOS使用virtualenv搭建独立的Python环境-python虚拟环境 virtualenv可以搭建虚拟且独立的python环境,可以使每个项目环境与其他项目独立开来,保持环境的干净,解 ...

  3. codevs 1163 访问艺术馆

    1163 访问艺术馆  时间限制: 1 s  空间限制: 128000 KB       题目描述 Description 皮尔是一个出了名的盗画者,他经过数月的精心准备,打算到艺术馆盗画.艺术馆的结 ...

  4. Java设计模式——组合模式

    JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...

  5. ORACLE object_id和data_object_id

    object_id和data_object_id 都是对象的唯一标识. object_id是对象的逻辑标识 data_object_id是对象的物理标识 对于没有物理存储的对象,data_object ...

  6. WebService 基础使用&cxf第三方Service使用

    1.通过Jax-ws自己发布一个webservice 解析:用webservice发布HelloWorld JAX-WS本质就是通过Socket来实现的.2.WSDL文档描述如何直接变成java代码 ...

  7. ORACLE服务端详细安装步骤(配图解)

    ORACLE服务端的安装及配置 l 将下载的安装包解压缩,双击[setup.exe]文件,系统检查监听参数,耐心等待,完成后出现如下界面,电子邮件可不填,"我希望..."建议不勾选 ...

  8. UISearchBar

    UISearchBar——方便用户搜索信息 在移动应用程序的世界里,用户对信息获取的速度要求非常高!iOS用户希望他们需要的信息能够迅速地,直观地展现在他们面前 因为UITableView的上下滚动能 ...

  9. Hibernate个人学习笔记(1)

    连接池c3p0所需jar包:Hiberbate开发包-lib-optional-c3p0下全部Jar包 Hiberbate连接池参数配置:Hiberbate开发包-project-etc-hibern ...

  10. ICMP

    (一)ICMP IP是一个尽力的不可靠的协议,IP不能提供差错控制(如果数据在传播过程中出现错误了),这个时候ICMP就起作用了. ICMP提供两个功能:差错的报告,查询. ICMP的ICMP包分为两 ...