成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Java如何比較兩個對象并獲取其中不相等的字段?

henry14 / 1576人閱讀

摘要:以下這些場景都需要我們對一個對象進行比較數(shù)據(jù)比對做單元測試斷言對象是否相等前端要求對不相等的字段進行高亮顯示這種需求其實是非常簡單的,但是如何優(yōu)雅地解決這一類需求呢通常的做法是重寫對象的方法。

聲明:本文屬原創(chuàng)文章,始發(fā)于 https://blog.csdn.net/dadiyan...。特此,同步發(fā)布到 sf,轉載請注明出處。

寫在前面

在工作中,我們經(jīng)常會遇到這樣的需求——比較兩個對象是否相等,如果不相等的話,取出不相等的字段。

以下這些場景都需要我們對一個對象進行比較:

數(shù)據(jù)比對

單元測試斷言對象是否相等

前端要求對不相等的字段進行高亮顯示

這種需求其實是非常簡單的,但是如何優(yōu)雅地解決這一類需求呢?

通常的做法是重寫對象的 equals 方法。但是重寫 equals 方法有很多缺點,例如:

每次對象屬性有變更,一定要記得再重寫(放心,你一定會忘記的

每個對象只能有一個 equals 方法,但是可能你會需要不同的比對規(guī)則

只能對比兩個對象是否相等,無法具體知道哪個屬性不等

自動生成的 equals 方法無法基于 getter 方法進行比對

對象來自第三方依賴,無法重寫 equals 方法

因此,實現(xiàn)一個通用的比對器可以減少很多不必要的麻煩,幫助我們很好地完成這一類的需求

緣起

我是在做數(shù)據(jù)同步的時候有這個需求,我要將數(shù)據(jù)庫的數(shù)據(jù)通過一定的規(guī)則導入到 ES 中,導入完成之后,如何比對兩邊的數(shù)據(jù)是否一致呢?這時候一個好用的比對器就是我非常好的幫手。

另外,我在做單元測試的時候發(fā)現(xiàn),經(jīng)常會需要將被測方法的返回值和期望的結果做 assertEquals 斷言這時這個比對器也非常有幫助。我發(fā)現(xiàn)很多同事經(jīng)常會遇到類似的需求。

于是,我找時間自己實現(xiàn)了一下。

實現(xiàn)

使用反射對傳入的對象進行比對,提供了基于字段的比較器和基于 Getter 方法的對比器,并且充分考慮擴展性,使用者可以重寫字段的比對規(guī)則。功能相對簡單,代碼實現(xiàn)也不難,而且做了很多注釋,具體實現(xiàn)可以直接查看源碼。

項目地址:https://github.com/dadiyang/e...

UML圖:

使用方法

因為已經(jīng)上傳到了 maven 倉庫中,我們使用非常方便:

添加 maven 依賴


    com.github.dadiyang
    equator
    1.0.1

初始化并調(diào)用方法

Equator equator = new GetterBaseEquator();
User user1 = new User(...);
User user2 = new User(...);
// 判斷屬性是否完全相等
equator.isEquals(user1, user2);
// 獲取不同的屬性
List diff = equator.getDiffFields(user1, user2);
擴展

我們可以通過繼承并重寫 isFieldEquals 方法自定義比對規(guī)則,例如我們在做單元測試的時候,對于 Date 類型的字段的比對,通常數(shù)據(jù)庫不保存毫秒數(shù),而我們 new 出來的 Date 對象則包含了毫秒數(shù),因此我們在對包含 Date 類型字段的對象做比對的時候需要忽略日期的毫秒數(shù)。這時就可以通過重寫isFieldEquals 方法來自定義了:

/**
 * 日期在數(shù)據(jù)庫不保存毫秒數(shù),因此需要特殊處理,比對時間時,忽略毫秒數(shù)
 *
 * @author dadiyang
 * @date 2019/3/23
 */
public class MmInsensitiveEquator extends GetterBaseEquator {
    @Override
    protected boolean isFieldEquals(FieldInfo fieldInfo) {
        if (fieldInfo.getFirstVal() instanceof Date) {
            Date first = (Date) fieldInfo.getFirstVal();
            Date second = (Date) fieldInfo.getSecondVal();
            if (Objects.equals(first, second)) {
                return true;
            }
            // 忽略毫秒數(shù)
            return Objects.equals(Math.round(first.getTime() / 1000), Math.round(second.getTime() / 1000));
        }
        return super.isFieldEquals(fieldInfo);
    }
}
后記

對象比對是一個非常小的需求,通常我們只會寫一個工具類來完成。但是寫一個工具類在各個項目間隨處拷貝,非常不優(yōu)雅,給整個團隊帶來很多不必要的維護成本。而且擴展性比較差,有任何差異就需要寫很多代碼去實現(xiàn)。

這時,如果我們從具體解決某一個需求的視角上升到解決一類需求,那么就能想出更加通用和優(yōu)雅的解決方案了。一個個具體的需求是無窮無盡的,以有限的人生去解決無限的需求,殆矣;但是將它們歸類之后,我們會發(fā)現(xiàn),需求的種類是有限的

因此解決一類一類問題,能讓我們擺脫無窮無盡的重復勞動,少加點班,多點時間陪陪家人哦。

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://m.hztianpu.com/yun/77732.html

相關文章

  • 【金三銀四】面試題之java基礎

    摘要:中,任何未處理的受檢查異常強制在子句中聲明。運行時多態(tài)是面向?qū)ο笞罹璧臇|西,要實現(xiàn)運行時多態(tài)需要方法重寫子類繼承父類并重寫父類中已 1、簡述Java程序編譯和運行的過程:答:① Java編譯程序?qū)ava源程序翻譯為JVM可執(zhí)行代碼--字節(jié)碼,創(chuàng)建完源文件之后,程序會先被編譯成 .class 文件。② 在編譯好的java程序得到.class文件后,使用命令java 運行這個 .c...

    Yangyang 評論0 收藏0
  • 【金三銀四】面試題之java基礎

    摘要:中,任何未處理的受檢查異常強制在子句中聲明。運行時多態(tài)是面向?qū)ο笞罹璧臇|西,要實現(xiàn)運行時多態(tài)需要方法重寫子類繼承父類并重寫父類中已 1、簡述Java程序編譯和運行的過程:答:① Java編譯程序?qū)ava源程序翻譯為JVM可執(zhí)行代碼--字節(jié)碼,創(chuàng)建完源文件之后,程序會先被編譯成 .class 文件。② 在編譯好的java程序得到.class文件后,使用命令java 運行這個 .c...

    Barrior 評論0 收藏0
  • 第3章:抽象數(shù)據(jù)類型(ADT)和面向對象編程(OOP) 3.5 ADT和OOP中等價性

    摘要:抽象函數(shù)引發(fā)的關系是等價關系。所以當且僅當通過調(diào)用抽象數(shù)據(jù)類型的任何操作不能區(qū)分它們時,兩個對象是相等的。必須為每個抽象數(shù)據(jù)類型適當?shù)囟x操作。一般來說,在面向?qū)ο缶幊讨惺褂檬且环N陋習。 大綱 什么是等價性?為什么要討論等價性?三種等價性的方式==與equals()不可變類型的等價性對象契約可變類型的等價性自動包裝和等價性 什么是等價性?為什么要討論等價性? ADT上的相等操作 ADT...

    Fundebug 評論0 收藏0
  • Flink 源碼解析 —— 深度解析 Flink 是如何管理好內(nèi)存?

    摘要:減少垃圾收集壓力因為所有長生命周期的數(shù)據(jù)都是在的管理內(nèi)存中以二進制表示的,所以所有數(shù)據(jù)對象都是短暫的,甚至是可變的,并且可以重用。當然,并不是唯一一個基于且對二進制數(shù)據(jù)進行操作的數(shù)據(jù)處理系統(tǒng)。 showImg(https://segmentfault.com/img/remote/1460000020044119?w=1280&h=853); 前言 如今,許多用于分析大型數(shù)據(jù)集的開源系...

    Edison 評論0 收藏0
  • js中Java式繼承

    摘要:中有三種不同的對象,三種對象的屬性和行為和下方的類似構造函數(shù)對象構造函數(shù)為的類定義名稱,任何添加到這個構造函數(shù)對象中的屬性都是類字段和類方法。 JavaScript中的Java式繼承 區(qū)別 Java類似的強類型面向?qū)ο笳Z言,類為 實例字段 他們是基于實例的屬性或變量,用以保存獨立對象的狀態(tài) 實例方法 他們是類的所有實例所共享的方法,由每個獨立的實例調(diào)用 類字段 這些屬性或者變量是屬于類...

    SillyMonkey 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<