前提

在Java编程中,我们经常要对引用数据类型的对象进行比较。引用数据类型的比较可以通过重写model的equals()方法实现,但是如果在开发中期才来重写equals()方法有可能对已有代码的正常运行有所影响。这种情况大家可以尝试本文推荐的方法对引用数据类型对象进行比较。步骤概述:

  1. 把Java对象转成JSONObject对象
  2. 使用JSONCompare对两者进行比较
  3. 如果需要忽略一些field可以使用Gson

准备

先准备两个Model:Company和Employee,其中在Company下有一个Employee的数组。

Company.java

package com.demo.model;import java.util.ArrayList;
import java.util.List;public class Company {private String companyName;private List<Employee> employees;public String getCompanyName() { return companyName; }public void setCompanyName(String companyName) { this.companyName = companyName; }public List<Employee> getEmployees() {if (this.employees == null) this.employees = new ArrayList<>();return employees; }public void addEmployee(Employee employee) { this.getEmployees().add(employee); }
}

Employee.java

package com.demo.model;public class Employee {private String employeeName;private int level;public String getEmployeeName() { return employeeName; }public void setEmployeeName(String employeeName) { this.employeeName = employeeName; }public int getLevel() { return level; }public void setLevel(int level) { this.level = level; }
}

可以看到,Company里除了有基本数据类型的成员变量外,也包含了引用数据类型Employee的数组,接下来我们会把Java对象转成JSONObject来进行比较。因为我们要用到JSONObject,所以还需要引入如下jar包。

开始

  • 直接调用equals()方法

当我们直接调用Company对象的equals()方法时,因为比较的是两者的toString()方法的结果,所以除非我们重写了equals()方法的实现,否则哪怕里面的值完全一样,equals()得到的结果也是false的。

package com.demo;import com.demo.model.Company;
import com.demo.model.Employee;public class GsonDemoApplication {public static void main(String[] args) {Company company1 = new Company();company1.setCompanyName("ABC");Company company2 = new Company();company2.setCompanyName("ABC");Employee employee1 = getEmployee1();Employee employee2 = getEmployee1();company1.addEmployee(employee1);company2.addEmployee(employee2);if (company1.equals(company2))System.out.println("Same");elseSystem.out.println("Different");}private static Employee getEmployee1() {Employee employee = new Employee();employee.setEmployeeName("Jay");employee.setLevel(2);return employee;}
}

结果:

Different
  • 转成JSONObject对象之后使用JSONCompare进行比较

因为我们要用到JSONObject和JSONCompare,所以需要引入如下jar包。

<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>20160810</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.skyscreamer/jsonassert -->
<dependency><groupId>org.skyscreamer</groupId><artifactId>jsonassert</artifactId><version>1.5.0</version><scope>test</scope>
</dependency>
<dependency><groupId>org.skyscreamer</groupId><artifactId>jsonassert</artifactId><version>RELEASE</version><scope>compile</scope>
</dependency>

使用skyscreamer提供的JSONCompare对两个JSONObject对象进行比较,得到JSONCompareResult,可以打印两者的差异。

package com.demo;import com.demo.model.Company;
import com.demo.model.Employee;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONCompare;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;public class GsonDemoApplication {public static void main(String[] args) {Company company1 = new Company();company1.setCompanyName("ABC");Company company2 = new Company();company2.setCompanyName("ABC");Employee employee1 = getEmployee1();Employee employee2 = getEmployee2();company1.addEmployee(employee1);company2.addEmployee(employee2);JSONObject object1 = new JSONObject(company1);JSONObject object2 = new JSONObject(company2);JSONCompareResult compareResult = JSONCompare.compareJSON(object1, object2, JSONCompareMode.STRICT);if (compareResult.passed())System.out.println("Same");else {System.out.println("Different");System.out.println("Failures:" + compareResult.getFieldFailures());System.out.println("Unexpected:" + compareResult.getFieldUnexpected());System.out.println("Missing:" + compareResult.getFieldMissing());System.out.println("Message:" + compareResult.getMessage());}}private static Employee getEmployee1() {Employee employee = new Employee();employee.setEmployeeName("Jay");employee.setLevel(2);return employee;}private static Employee getEmployee2() {Employee employee = new Employee();employee.setEmployeeName("Susan");employee.setLevel(3);return employee;}
}

结果:

Different
Failures:[org.skyscreamer.jsonassert.FieldComparisonFailure@7a81197d, org.skyscreamer.jsonassert.FieldComparisonFailure@5ca881b5]
Unexpected:[]
Missing:[]
Message:employees[0].employeeName
Expected: Jaygot: Susan; employees[0].level
Expected: 2got: 3
  • 使用JSONCompare避免因数组元素顺序的影响

JSONCompare比较的时候是根据key来取值比较的,所以field的顺序可以不用管,但是数组里元素的顺序呢?只要我们使用JSONCompareMode.LENIENT模式就能够忽略数组元素顺序的影响,如果不想忽视这个影响,可以像上例一样使用JSONCompareMode.STRICT模式。

package com.demo;import com.demo.model.Company;
import com.demo.model.Employee;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONCompare;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;public class GsonDemoApplication {public static void main(String[] args) {Company company1 = new Company();company1.setCompanyName("ABC");Company company2 = new Company();company2.setCompanyName("ABC");Employee employee1 = getEmployee1();Employee employee2 = getEmployee2();company1.addEmployee(employee1);company1.addEmployee(employee2);company2.addEmployee(employee2);company2.addEmployee(employee1);JSONObject object1 = new JSONObject(company1);JSONObject object2 = new JSONObject(company2);JSONCompareResult compareResult = JSONCompare.compareJSON(object1, object2, JSONCompareMode.LENIENT);if (compareResult.passed())System.out.println("Same");else {System.out.println("Different");System.out.println("Failures:" + compareResult.getFieldFailures());System.out.println("Unexpected:" + compareResult.getFieldUnexpected());System.out.println("Missing:" + compareResult.getFieldMissing());System.out.println("Message:" + compareResult.getMessage());}}private static Employee getEmployee1() {Employee employee = new Employee();employee.setEmployeeName("Jay");employee.setLevel(2);return employee;}private static Employee getEmployee2() {Employee employee = new Employee();employee.setEmployeeName("Susan");employee.setLevel(3);return employee;}
}

结果:

Same
  • 如何忽视部分field的影响

在某些业务场景,我们需要比较两个对象的同时又要忽略其中的一些field,这个时候我们就可以使用Gson。

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.2</version>
</dependency>

下例中,虽然companyName是不一样的,但是我们在转json的时候跳过了这个field,所以也就不影响我们比较的结果。

package com.demo;import com.demo.model.Company;
import com.demo.model.Employee;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONCompare;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;public class GsonDemoApplication {public static void main(String[] args) {Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {@Overridepublic boolean shouldSkipField(FieldAttributes fieldAttributes) {return fieldAttributes.getName().equals("companyName");}@Overridepublic boolean shouldSkipClass(Class<?> aClass) {return false;}}).create();Company company1 = new Company();company1.setCompanyName("ABC");Company company2 = new Company();company2.setCompanyName("ABCD");Employee employee1 = getEmployee1();Employee employee2 = getEmployee2();company1.addEmployee(employee1);company1.addEmployee(employee2);company2.addEmployee(employee2);company2.addEmployee(employee1);JSONObject object1 = new JSONObject(gson.toJson(company1));JSONObject object2 = new JSONObject(gson.toJson(company2));JSONCompareResult compareResult = JSONCompare.compareJSON(object1, object2, JSONCompareMode.LENIENT);if (compareResult.passed())System.out.println("Same");else {System.out.println("Different");System.out.println("Failures:" + compareResult.getFieldFailures());System.out.println("Unexpected:" + compareResult.getFieldUnexpected());System.out.println("Missing:" + compareResult.getFieldMissing());System.out.println("Message:" + compareResult.getMessage());}}private static Employee getEmployee1() {Employee employee = new Employee();employee.setEmployeeName("Jay");employee.setLevel(2);return employee;}private static Employee getEmployee2() {Employee employee = new Employee();employee.setEmployeeName("Susan");employee.setLevel(3);return employee;}
}

结果:

Same

这就是本篇文章的全部内容,需要另外提出的一点事,Gson还有很多强大的功能,大家可以自己探索哦~

使用JSONObject比较Java复杂对象相关推荐

  1. net.sf.json在处理json对象转换为普通java实体对象时的问题和解决方案

    我使用的net.sf.json是json-lib-2.4-jdk15.jar,把json对象转换为普通java实体对象时候有个问题,josn对象转换为java对象之后,json串里面的那几个小数点的值 ...

  2. java类对象转化成字符串_String类型字符串(xml格式)转换成java对象类型

    使用到的包: 1. 2. 将字符串类型的字符串转换成的Java的对象时,需要先将字符的格式转换成JSON格式的字符串(所以用到了json.jar包),在使用JSON格式的字符串转换成的Java的对象类 ...

  3. js接收java数组对象_js接收并转化Java中的数组对象的方法

    在做项目时,要向ocx控件下发命令,就要在js中得到java中的对象,然后拼成一种格式,下发下去...当对象是一个时比较简单,但如果对象是一个数组时,就略显麻烦了. 开始我以为有简单的方式,可以直接进 ...

  4. JSON对象转为Java类对象

    本文讲述两种方法,使JSON对象转为Java类对象.基于FastJson1 对于以下的JSON对象: {"message": "成功","code&q ...

  5. Java基于对象基础 基于对象和面向对象的区别(转)

    Java基于对象基础 基于对象和面向对象的区别 JavaScript设计者想把javascript语言设计成基于对象(object-based)的语言,他想把这个与面向对象(object-orient ...

  6. java 嵌套对象转xml_Gson对Java嵌套对象和JSON字符串之间的转换 | 学步园

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,具有良好的跨平台特性.近几年来已经和XML一样成为C/S架构中广泛采用的数据格式.有关JSON的更多知识, ...

  7. Java Robot对象实现服务器屏幕远程监视

    Java Robot对象实现服务器屏幕远程监视2006-01-16 17:33 作者: xiepan110 出处: BLOG 责任编辑:方舟 摘要: 有时候,在Java应用程序开发中,如:远程监控或远 ...

  8. java 复制对象有哪些方式

    2019独角兽企业重金招聘Python工程师标准>>> java 复制对象有哪些方式 Apache的 Common beanutils库 org.apache.commons.bea ...

  9. java常见对象_Java/10_Java常见对象.md at master · DuHouAn/Java · GitHub

    Java常见对象 Arrays Arrays:针对数组进行操作的工具类. Arrays的常用成员方法: public static String toString(int[] a) //把数组转成字符 ...

  10. Java中对象的储存区

    文章目录 1 两个重要的问题 2 C语言中数据的存储区 3 Java中对象的储存区 4 Java为什么采用动态内存分配? 4 为什么基本类型是特例? 1 两个重要的问题 对象的数据位于何处? 如何控制 ...

最新文章

  1. Linux服务器安装软件
  2. Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理
  3. Ubuntu14.04安装编译ffmpeg
  4. java cordova_java – Cordova android后台插件在5分钟后被杀死
  5. html border阴影效果_HTML | 简易相册制作
  6. android 始终显示overflow菜单
  7. kafka入门介绍(转载)
  8. excel进销存管理系统_【实例分享】勤哲Excel服务器做企业进销存财务管理系统...
  9. 如何在Java中对Collection对象进行排序?
  10. 深入浅出VC++串口编程--短信应用开发
  11. python如何在列表中查找元素位置_查找元素在list中的位置以及折半查询
  12. ArcGIS——数据库与服务备份(一、oracle中的geodatabase备份使用impdp与expdp)
  13. Seinfeld(杭电3351)
  14. 笔记:Java 性能优化权威指南 第5章 Java 应用性能分析
  15. grandMA2 onPC 3.1.2.5的DMX参数摸索
  16. 刘未鹏的博中带的技术博客链接
  17. 什么是嵌入式系统?嵌入式系统应该如何学习?
  18. 自定义Android视频播放器 - 切换横竖屏
  19. 职场中干好工作的18准则
  20. zxing换行_为什么我的word里的横线上写完一行字不能自动换行,?

热门文章

  1. 201704 创建财务凭证函数
  2. 计算机网络ip 地址怎么查询系统,怎么查看电脑的ip地址_查看ip地址命令介绍 - 驱动管家...
  3. 计算机桌面颜色怎么换,电脑桌面字体颜色怎么改
  4. Java一般要学多久?
  5. 《Deep Semantic Feature Learning for Software Defect Prediction》论文笔记
  6. 2019-04-26周五宁波和杭州都下雨了,晚饭的鱼粉好大份哦,这是我第一次吃鱼粉!Hhhhhhhh下雨了就给吃点面才暖和,辛苦快递小哥哥了呀,其实这家店就在食堂我看见很多次了懒得买,外卖好像更便宜!
  7. 一位阿里p9的自述——关于年薪和资产
  8. 前端之 HTML 知识点扫盲
  9. 嵌入式linux模块复位,嵌入式linux下复位声卡驱动
  10. LeetCode 452 用最少的箭头射爆气球