在Java中如何比較兩個對象淺析

Common Lang 中的 Builder 包內提供瞭一個 DiffBuilder 類,可以比較兩個對象,並返回不同的部分。

  1. 首先在要比較對象的類中實現 Diffable 接口,然後實現 DiffResult diff(T obj)  方法。
  2. 在DiffResult diff(T obj)  方法中,新建一個 DiffBuilder 對象,把需要比較的類屬性一一放入 DiffBuilder 中。

DiffBuilder 的構造函數有三個入參,lhs 是當前對象,rhs 是要比較的對象,style 是比較結果輸出的格式。

DiffBuilder(final T lhs, final T rhs,
        final ToStringStyle style)

假設有一個 Person 類定義瞭三個屬性 name、age 和 smoker。以下是使用不同的 ToStringStyle 所對應的輸出內容。

ToStringStyle 說明 輸出
SHORT_PREFIX_STYLE 簡短 Person[name=deniro,smoker=false] differs from Person[name=jack,smoker=true]
DEFAULT_STYLE 默認 org.apache.commons.lang3.builder.Person@9f70c54[name=deniro,smoker=false] differs from org.apache.commons.lang3.builder.Person@234bef66[name=jack,smoker=true]。
MULTI_LINE_STYLE 多行 org.apache.commons.lang3.builder.Person@9f70c54[
name=deniro
smoker=false
] differs from org.apache.commons.lang3.builder.Person@234bef66[
name=jack
smoker=true
]
NO_FIELD_NAMES_STYLE 不包含類屬性名 org.apache.commons.lang3.builder.Person@9f70c54[deniro,false] differs from org.apache.commons.lang3.builder.Person@234bef66[jack,true]。
SIMPLE_STYLE 簡潔 deniro,false differs from jack,true。
NO_CLASS_NAME_STYLE 不包含類名 [name=deniro,smoker=false] differs from [name=jack,smoker=true]。
JSON_STYLE JSON {“name”:”deniro”,”smoker”:false} differs from {“name”:”jack”,”smoker”:true}。

感覺 NO_CLASS_NAME_STYLE 與 JSON_STYLE 看的更清楚。

完整示例:

public class Person implements Diffable<Person> {

    private static final Logger log = LoggerFactory.getLogger(Person.class);

    String name;
    int age;
    boolean smoker;

    public DiffResult diff(Person obj) {
        // No need for null check, as NullPointerException correct if obj is null
        return new DiffBuilder(this, obj, ToStringStyle.SHORT_PREFIX_STYLE)
                .append("name", this.name, obj.name)
                .append("age", this.age, obj.age)
                .append("smoker", this.smoker, obj.smoker)
                .build();
    }

    public static void main(String[] args) {
        Person a = new Person();
        a.name = "deniro";
        a.age = 22;
        a.smoker = false;

        Person b = new Person();
        b.name = "jack";
        b.age = 22;
        b.smoker = true;

        DiffResult result = a.diff(b);
        log.info("result -> {}。", result);
    }
}

輸出:

result -> Person[name=deniro,smoker=false] differs from Person[name=jack,smoker=true]。

如果是個大類,那麼需要很多個 append 方法把這個大類的屬性放到 DiffBuilder 中,不太方便。可以寫個程序生成 DiffBuilder 初始化代碼,或者嘗試用反射來優化這部分代碼。

反射擴展:

(1)獲取對象所屬類的Class方法。

Class c = Class.forName("包.類名稱");

(2)獲得該類的所有Filed(不包括父類)。

Field[] fields = c.getDeclaredFields();

(3)將所有屬性的訪問權限設為true。

因為JavaBean中所有的屬性訪問權限都是private,所以無法直接獲得所有屬性,因此我們必須獲得其訪問權限,通過下面的方法完成:

setAccessible(true);

(4)輸出對象屬性

f.getField(對象名稱);

(5)獲取字段名

fields[j].getName()

(6)獲取字段值

fields[j].get(obj)

參考資料

commons.apache.org/proper/comm…

總結

到此這篇關於在Java中如何比較兩個對象的文章就介紹到這瞭,更多相關Java比較兩個對象內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: