算法:

1. nul l== null

2. null != 任何对象

3. 复杂对象直接调用Object的equals()方法,若相等直接返回,否则4

4.遍历对象的所有Field, 递归比较每个Field

package com.tuniu.dusk;

import java.lang.reflect.Array;
import java.lang.reflect.Field;

import org.apache.commons.lang3.ClassUtils;

public class ObjectUtil {
	/*
	 * 1.null == null 
	 * 2.null != Object 
	 * 3.object.equals(other) is true,return
	 * true 4.compare all Fields
	 */
	public static boolean equals(Object obj, Object other) {
		if (obj == null && other == null){
			return true;
		}
		
		if(obj != null && other == null){
			return false;
		}
		if(obj != null && other == null){
			return false;
		}
		
		return compareNotNull(obj,other);
	}
	//非空比较
	private static boolean compareNotNull(Object obj, Object other){
		if(obj.equals(other)){
			return true;
		}
		Class type = obj.getClass();
		if(type != other.getClass()){
			return false;
		}
		
		//简单类型
		if(ClassUtils.isPrimitiveOrWrapper(type)){
			return comparePrimitiveType(obj, other);
		}
		//数组
		if(type.isArray()){
			return compareArray(obj, other);
		}
		
		Field[] fields = obj.getClass().getDeclaredFields();
		for(Field field : fields){
			try {
				field.setAccessible(true);
				Object tmp1=field.get(obj);
				Object tmp2=field.get(other);
				if(!equals(tmp1, tmp2)){
					return false;
				}
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
			
		}
		return true;
	}
	
	private static boolean comparePrimitiveType(Object obj, Object other){
		if(obj.getClass().isPrimitive()){
			return obj==other;
		}else{
			return obj.equals(other);
		}
	}
	
	private static boolean compareArray(Object obj, Object other) {
		int len = Array.getLength(obj);
		if (len != Array.getLength(other)){
			return false;
		}
		for(int i=0;i



测试用例:


package com.tuniu.dusk;
 
import java.util.Arrays;
import java.util.List;
 
import org.junit.Test;
 
import com.tuniu.operation.platform.tsg.base.core.utils.JsonUtil;
 
public class ObjectUtilTest {
 
	@Test
	public void testPrimitiveType() {
		int a=1;
		int b=13;
		System.out.println(ObjectUtil.equals(a, b));
		System.out.println(ObjectUtil.equals(a, 1));
	}
	@Test
	public void testArray() {
		int a[]={1};
		int b[]={13};
		int c[]={new Integer(13)};
		System.out.println(ObjectUtil.equals(a, b));
		System.out.println(ObjectUtil.equals(c, b));
	}
	@Test
	public void testString() {
		String str1="hello";
		String str2="world";
		String str3=new StringBuffer("world").toString();
		System.out.println(ObjectUtil.equals(str1, str2));
		System.out.println(ObjectUtil.equals(str2, str3));
	}
	@Test
	public void testObject() {
		Student stu1=new Student(1, "zhangsan", 1);
		Student stu2=new Student(1, "zhangsan", 1);
		Student stu3=new Student(3, "zhangsan", 1);
		Student stu4=new Student(3, "zhangsan", 1);
		stu4.role="班长";
		System.out.println(ObjectUtil.equals(stu1, stu2));
		System.out.println(ObjectUtil.equals(stu2, stu3));
		System.out.println(ObjectUtil.equals(stu4, stu3));
	}
	@Test
	public void testList() {
		Student stu1=new Student(1, "zhangsan", 1);
		Student stu2=new Student(1, "zhangsan", 1);
		List list1=Arrays.asList(1,2,3);
		List list2=Arrays.asList(1,2,3);
		List list3=Arrays.asList(4,5,3);
		List list4=Arrays.asList(1,2,stu1);
		List list5=Arrays.asList(1,2,stu2);
		System.out.println(ObjectUtil.equals(list1, list2));
		System.out.println(ObjectUtil.equals(list1, list3));
		System.out.println(ObjectUtil.equals(list4, list5));
	}
 
	@Test
	public void testJson() throws Exception{
//		String json="{\"hotelId\":377954629,\"vendorId\":30259,\"vendorHotelId\":\"270613\",\"chineseName\":\"樟宜机场皇冠广场酒店\",\"englishName\":\"Crowne Plaza Changi Airport\",\"cityCode\":47109,\"choice\":[{\"seq\":1,\"desc\":\"1 张特大床\"}]},\"wifi\":0,\"broadband\":0,\"hotelAddress\":\"75 Airport Boulevard\",\"hotelPhone\":\"65-68-235300\",\"timeZone\":\"GMT+8\",\"currencyCode\":\"SGD\",\"orginalAvgRmbPrice\":381.29,\"price\":283.66,\"rmbPrice\":381.29,\"cashBack\":0,\"rmbCashBack\":0,\"instantSubtract\":0,\"rmbInstantSubtract\":0,\"instantConfirm\":0,\"roomRate\":221.00,\"rmbRoomRate\":1078.79,\"taxAndFee\":62.66,\"rmbTaxAndFee\":-697.50,\"isJiBao\":1,\"product\":{\"productLineTypeId\":80,\"productLineDestId\":12581234,\"productId\":5199957},\"departs\":[{\"departDate\":\"2016-08-01\",\"price\":283.66,\"roomRate\":221.00,\"taxAndFee\":62.66,\"rmbPrices\":381.29,\"rmbRoomRate\":1078.79,\"rmbTaxAndFee\":160.29,\"cashBack\":0,\"rmbCashBack\":0,\"breakfastNum\":\"无早\",\"roomCount\":0,\"status\":\"ACTIVE\"}],\"promotionRule\":null,\"cancelInfos\":[{\"type\":\"不可取消\",\"guaranteeMode\":2,\"guaranteePrice\":283.66,\"rmbGguaranteePrice\":381.29,\"desc\":[\"订单确认后不可取消,如未入住酒店将扣除全额房费。订单一经预订,入住信息不可变更。\"],\"checkArriveTime\":0,\"cancelTime\":null,\"arriveStartTime\":null,\"arriveEndTime\":null}],\"surcharges\":null,\"tips\":[\"请您在十五分钟内完成订单填写,以免酒店房间被他人订完。\",\"酒店通常在15:00之后办理入住,如您在此时间之前到店,可能需要等待方能入住,具体以酒店安排为准。\",\"酒店入住提示:\n<p><b>出行提示</b> <br /><ul>  <li>只有经过登记的住客才可进入客房。</li> <li>某些设施可能有限制,旅客可以使用预订确认信息上的联系方式向酒店查询详情。</li> </ul></p><p><b>费用</b> <br /><p>以下费用和押金由酒店在提供服务、办理入住或退房手续时收取。</p> <ul> <li>自助式早餐收费:每人大约 SGD 35</li>  <li>客房内高速有线上网费用:每 24 小时 SGD21.18(价格可能有所波动)</li>     <li>自助泊车费用:每天 SGD57.60</li>         <li>额外收费提供折叠床</li>   </ul> <p>上面所列内容可能并不完整。这些费用和押金可能不包括税款,并且可能会随时发生变化。</p></p>\",\"在办理登记入住时您必须出示带照片的身份证件。在您预订时即向您的信用卡收取费用。床型与吸烟喜好无法保证。您的预订已预先付款,并且保证若延时抵达仍可入住。费用总计包括所有房费和税款,以及预订费。任何杂费,包括停车费、电话费和客房送餐费将由酒店直接向您收取。\",\"预订条款和条件: http://travel.ian.com/index.jsp?pageName=userAgreement&locale=zh_CN&cid=496922\",\"订单确认成功后,酒店有权因为信用卡无效等原因在72小时内取消订单,请注意查收通知短信或邮件。\",\"因房型紧张,酒店将在订单确认成功后的72个小时之内,直接从您登记的信用卡中收取费用。\"],\"quotationInformation\":{\"rmbPrices\":[381.29],\"surcharges\":[],\"breakfastCount\":[0],\"lunchCount\":[0],\"dinnerCount\":[0],\"refund\":{\"returnable\":false,\"refundRules\":[],\"nonRefundableRanges\":[]}},\"extras\":[{\"key\":\"bed1\",\"value\":\"14\"},{\"key\":\"supplierType\",\"value\":\"E\"},{\"key\":\"smokingPreferences\",\"value\":\"NS\"},{\"key\":\"rateKay\",\"value\":\"67a1b1ae-628e-438c-a4b2-5fa0b28ebc2f-5208\"},{\"key\":\"total\",\"value\":\"283.66\"}],\"totalPrice\":283.66,\"rmbTotalPrice\":381.29,\"checkInTime\":\"15:00\",\"hotelTags\":[{\"hotelTagCode\":9,\"hotelTagName\":\"优选亲子酒店\",\"hotelTagPriority\":2}]}";
		String json="{\"hotelId\":377954629,\"vendorId\":30259,\"departs\":[{\"departDate\":\"2016-08-01\",\"price\":283.66,\"roomRate\":221.00,\"taxAndFee\":62.66,\"rmbPrices\":381.29,\"rmbRoomRate\":1078.79,\"rmbTaxAndFee\":160.29,\"cashBack\":0,\"rmbCashBack\":0,\"breakfastNum\":\"无早\",\"roomCount\":0,\"status\":\"ACTIVE\"}]}";
		Object obj=JsonUtil.toObject(json, Object.class);
		Object other=JsonUtil.toObject(json, Object.class);
		System.out.println(obj==other);
		System.out.println(obj.equals(other));
		System.out.println(ObjectUtil.equals(obj, 12));
		System.out.println(ObjectUtil.equals(obj, other));
	}
}


测试结果:

false
true
false
true
false
true
false
true
true
false
true
true
false
false
false
true