比較任意兩個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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM