zoukankan      html  css  js  c++  java
  • 比较任意两个JSON串是否相等(比较对象是否相等)JAVA版

         废话少说,直接入题。

         在面向对象语言中,经常会比较两个对象是否相等,而比较的大多是实体类实例,也就是封装数据的那些类实例,或者是Map、List互相嵌套成的复杂数据结构。

         比较对象是否相等,常见的思路是重写equals方法,但鉴于对象的种类多变,嵌套层次复杂,仅仅靠重写equals是很难实现的。

         小菜的思路是可以把对象序列化,由于这些对象均是用来表达数据结构,因此可以直接转换成JSON字符串,用字符串来描述数据结构,避免实现Serializable接口。将对象序列化成字符串后,比较是否相等就相对简单了。

         小菜提供的正是比较两个JSON串是否相等的方法,并不是说JSON串完全一样才叫相等,对于List(或数组)结构而言,如果仅仅是元素排列顺序不同,也是相等的。

         为了保证方法的准确性,请传入标准的JSON串,也就是说key也要加双引号。用过js的童鞋可能会被误导:我在js中写的JSON,key可以不加双引号啊!实际上,你在js中写的是js语言的Object,并不是JSON,只不过它的语法和JSON非常像而已,JSON仅仅是一种字符串规范,而且真正的JSON只有一种,那就是key加了双引号的!

         另外,此方法不依赖任何第三方包。

         最后声明,由于数据结构复杂,小菜对这个方法不可能进行遍历性测试,所以这个方法的准确性有待考究,请谨慎使用!如有问题,欢迎反馈!

      1 import java.util.regex.Matcher;
      2 import java.util.regex.Pattern;
      3 
      4 /**
      5  * 比较两个json串是否相同
      6  * @param j1  第一个json串(json串中不能有换行)
      7  * @param j2 第二个json串(json串中不能有换行)
      8  * @return 布尔型比较结果
      9  */
     10 public static boolean jsonEquals(String j1,String j2){
     11   
     12   //将json中表示list的[]替换成{}。思想:只保留层次结构,不区分类型
     13   //这样直接替换,可能会导致某些value中的符号也被替换,但是不影响结果,因为j1、j2的变化是相对的
     14   j1 = j1.replaceAll("\[", "{");
     15   j1 = j1.replaceAll("]", "}");
     16   j2 = j2.replaceAll("\[", "{");
     17   j2 = j2.replaceAll("]", "}");
     18   //将json中,字符串型的value中的{},字符替换掉,防止干扰(并没有去除key中的,因为不可能存在那样的变量名)
     19       //未转义regex:(?<=:")(([^"]*{[^"]*)|([^"]*}[^"]*)|([^"]*,[^"]*))(?=")
     20   Pattern pattern = Pattern.compile("(?<=:")(([^"]*\{[^"]*)|([^"]*\}[^"]*)|([^"]*,[^"]*))(?=")");
     21       j1 = cleanStr4Special(j1, pattern.matcher(j1));
     22       j2 = cleanStr4Special(j2, pattern.matcher(j2));
     23   //转义字符串value中的空格
     24   //未转义regex:"[^",]*?s+?[^",]*?"
     25   pattern = Pattern.compile(""[^",]*?\s+?[^",]*?"");
     26       j1 = cleanStr4Space(j1, pattern.matcher(j1));
     27       j2 = cleanStr4Space(j2, pattern.matcher(j2));
     28       //现在可以安全的全局性去掉空格
     29       j1 = j1.replaceAll(" ", "");
     30       j2 = j2.replaceAll(" ", "");
     31   //调用递归方法
     32   return compareAtom(j1,j2);
     33 }
     34 
     35 /**
     36  * 比较字符串核心递归方法
     37  * @param j1
     38  * @param j2
     39  * @return
     40  */
     41 private static boolean compareAtom(String j1,String j2){
     42   
     43   if(!j1.equals("?:"?"")){
     44     //取出最深层原子
     45     String a1 = j1.split("\{",-1)[j1.split("\{",-1).length-1].split("}",-1)[0];
     46     String a2 = j2.split("\{",-1)[j2.split("\{",-1).length-1].split("}",-1)[0];
     47     String j2_ = j2;
     48     String a2_ = a2;
     49     //转换成原子项
     50     String i1[] = a1.split(",");
     51     //在同级原子中寻找相同的原子
     52     while(!a2.startsWith(",") &&
     53         !a2.endsWith(",") &&
     54         a2.indexOf(":,")<0 &&
     55         a2.indexOf(",,")<0
     56        ){
     57       //遍历消除
     58       for(String s : i1){
     59         a2_ = a2_.replace(s,"");
     60       }
     61       //此时a2_剩下的全是逗号,如果长度正好等于i1的长度-1,说明相等
     62       if(a2_.length() == i1.length-1){
     63         //相等则从j1、j2中消除,消除不能简单的替换,因为其他位置可能有相同的结构,必须从当前位置上消除
     64         int index = 0;
     65         index = j1.lastIndexOf("{" + a1 + "}");
     66         j1 = j1.substring(0, index)+j1.substring(index).replace("{" + a1 + "}", "?:"?"");
     67         index = j2.lastIndexOf("{" + a2 + "}");
     68         j2 = j2.substring(0, index)+j2.substring(index).replace("{" + a2 + "}", "?:"?"");
     69         //递归
     70         return compareAtom(j1, j2);
     71       }else{
     72         //寻找下一个同级原子
     73         j2_ = j2_.replace("{" + a2 + "}", "");
     74         a2 = j2_.split("\{",-1)[j2_.split("\{",-1).length-1].split("}",-1)[0];
     75         a2_ = a2;
     76       }
     77     }
     78     return false;
     79   }else{
     80     //比较是否相同
     81     return j1.equals(j2);
     82   }
     83 }
     84 
     85 /**
     86  * json字符串特殊字符清理辅助方法
     87  * @param j 需要清理的json字符串
     88  * @param matcher 正则表达式匹配对象
     89  * @return 净化的json串
     90  */
     91 private static String cleanStr4Special(String j,Matcher matcher){
     92   String group = "";
     93   String groupNew = "";
     94   while(matcher.find()){
     95     group = matcher.group();
     96     groupNew = group.replaceAll("\{", "A");
     97     groupNew = groupNew.replaceAll("}", "B");
     98     groupNew = groupNew.replaceAll(",", "C");
     99     j = j.replace(group, groupNew);
    100   }
    101   return j;
    102 }
    103 
    104 /**
    105  * json串字符串类型的value中的空格清理辅助方法
    106  * @param j 需要清理的json字符串
    107  * @param matcher 正则表达式匹配对象
    108  * @return 净化的json串
    109  */
    110 private static String cleanStr4Space(String j,Matcher matcher){
    111     String group = "";
    112       String groupNew = "";
    113       while(matcher.find()){
    114           group = matcher.group();
    115           groupNew = group.replaceAll(" ", "S");
    116           j = j.replace(group, groupNew);
    117       }
    118       return j;
    119 }
    View Code
  • 相关阅读:
    lua学习项目笔记
    Jenkins 安装、配置与项目新建及构建
    Gitlab的安装及项目新建
    PHP常见排序算法
    抽象类和接口的区别
    分布式版本控制系统Git的安装及使用
    深入解析OpenCart的代理类proxy
    PHP模式设计之单例模式、工厂模式、注册树模式、适配器模式、观察者模式
    linux命令行传递参数定期执行PHP文件
    php类中的$this,static,const,self这几个关键字使用方法
  • 原文地址:https://www.cnblogs.com/iyangyuan/p/3866142.html
Copyright © 2011-2022 走看看