java比较两个对象重写,不重写equals进行两个对象间的深度比较
背景
我們知道在Java中比較兩個對象是否相同,可以有多種方法,最常見的就是 == 和 equals 方法。但是由于==對比的是對象引用本身,因此重寫equals才是最常用和可靠的比較兩個對象是否相同的方法(當然重寫equals同時意味著可能需要重寫hashCode)
對于==和equals的異同,可以參考《阿里java規范》中對于Integer的一個很有意思的例子,因為Integer在實現時對-127~127的數字做了一個緩存,因此:
Integer i1 = 1, i2 = 1 ;
i1==i2; // true
i1.equals(i2); // true
Integer i1 = 1024, i2 = 1024 ;
i1==i2; // false
i1.equals(i2); // true
但是在實際搬磚的過程中,很多時候對于每個需要比較的對象都重寫equals是很麻煩的(有時這種重寫equals可能導致新的依賴情況),而且對于一些無法修改源碼的類重寫equals也是不可行的。
因此想到了通過反射來處理這樣一些情況,就能比較簡單的進行一些深度的比較,從而不需要重寫每個比較對象的equals方法,也降低了編碼時候的侵入性。
方案
因此基于以上想法,特別將這種利用反射來實現的深度比較封裝了一個簡單的功能類,能比較方便的實現對比的功能。所以這其實是一篇廣告文,騙你去訪問我的github的,沒想到吧!哈哈哈!
重要的廣告無恥的做完3次之后,更無恥的講下怎么用好了!還是沒想到吧,哈哈哈!
使用示例
具體的使用示例如下:
// 初始化并設置對比屬性
CompareUtils compareUtils = CompareUtils.build();
compareUtils.ignoreAnnotation(); // 是否忽略自定的 @NotCompare 注解
compareUtils.ignoreCollection() // 是否忽略對Collection類型的屬性的比較(e.g. List)
compareUtils.ignoreMap(); // 是否忽略對Map類型的屬性的比較
// 直接使用isDifferent方法來比較得出是否是相同的對象
Boolean isDifferent = compareUtils.isDifferent(firstObject, secondObject);
當然對于初始化和設置屬性,推薦使用這種方式:
CompareUtils utils = CompareUtils.build()
.includeAnnotation()
.includeCollection()
.includeMap();
具體屬性設置說明
ignoreAnnotation/includeAnnotation : 鑒于靈活性的考慮,在對比中可能需要忽略一些不關注的屬性值是否相同,因此提供了一個 @NotCompare 的注解,缺省情況下會跳過使用了注解的屬性,但是可以通過該設置來選擇是否開啟跳過注解這一功能;
ignoreCollection/includeCollection : 缺省情況下會對比對象中Collection類型的屬性,但是可以通過該方法來開啟或關閉這一行為
ignoreMap/includeMap : 缺省情況下會對比對象中Map類型的屬性,但是可以通過該方法來開啟或關閉這一行為
注意點
對比的對象 不能有遞歸嵌套
通過一些會 增加屬性數量 的方法生成的對象(比如Mokito.mock的對象),會造成 比對結果不準確,因為工具類在缺省情況下會將所有的屬性都進行比較,而增加屬性數量方法生成的對象,可能包含了一些額外的不相同的屬性,造成本應該相同的對象最后存在不同的情況
總結
以上是生活随笔為你收集整理的java比较两个对象重写,不重写equals进行两个对象间的深度比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 自动验证 正则表达,使用正则表达
- 下一篇: oracle11g 01031,Orac