算法:
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