我需要比較不包括某些欄位的同一類的兩個物件。
public final class Class1 {
private String a;
private String b;
private String c;
:
:
:
private String z;
private Date createdAt;
private Date updatedAt;
}
除了 createdAt 和 updatedAt 值之外,如何確定上述類的兩個物件是否相等?由于這個類的欄位很多,我不想一一比較。
請不要提供 AssertJ 的遞回比較解決方案,因為我不需要它用于 UnitTest。
先感謝您!
uj5u.com熱心網友回復:
如果覆寫Object::equalsandObject::hashCode不是一個選項,我們可以使用ComparatorAPI來構造一個相應的比較器:
final Comparator<Class1> comp = Comparator.comparing(Class1::getA)
.thenComparing(Class1::getB)
.thenComparing(Class1::getC)
.
.
.
.thenComparing(Class1::getZ);
不幸的是,如果不比較所有應該相等的欄位,就無法做到這一點。
uj5u.com熱心網友回復:
嘗試像下面這樣覆寫 equals 方法:
import java.util.Date;
import java.util.Objects;
public final class Class1 {
private String a;
private String b;
private String c;
private String z;
private Date createdAt;
private Date updatedAt;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Class1 class1 = (Class1) o;
return Objects.equals(a, class1.a) && Objects.equals(b, class1.b) && Objects.equals(c, class1.c) && Objects.equals(z, class1.z);
}
@Override
public int hashCode() {
return Objects.hash(a, b, c, z);
}
}
uj5u.com熱心網友回復:
不寫任何代碼的最快方法是 Lombok
Lombok 是 Java 中最常用的庫之一,它從您的專案中洗掉了大量樣板代碼。如果您需要閱讀更多有關它的功能和功能的資訊,請訪問此處。
實作您需要的方法非常簡單:
// Generate the equals and HashCode functions and Include only the fields that I annotate with Include
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Getter // Generate getters for each field
@Setter // Generate setters for each field
public class Class1
{
@EqualsAndHashCode.Include // Include this field
private Long identity;
private String testStr1; // This field is not annotated with Include so it will not be included in the functions.
// ... any other fields
}
Lombok 可以做的遠不止這些。有關更多資訊,@EqualsAndHashCode請參閱此。
您始終可以使用@EqualsAndHashCode.Exclude更快的解決方案來解決您的用例:
@EqualsAndHashCode
@Getter // Generate getters for each field
@Setter // Generate setters for each field
public final class Class1 {
private String a;
private String b;
private String c;
:
:
:
private String z;
@EqualsAndHashCode.Exclude
private Date createdAt;
@EqualsAndHashCode.Exclude
private Date updatedAt;
}
uj5u.com熱心網友回復:
除了 Comparator 和hashCode()/equals方法,您還可以使用反射。
- 創建注釋以排除某些欄位:
黑名單示例:
@Retention(RetentionPolicy.RUNTIME) //
@Target(ElementType.FIELD) //on class level
public @interface IngoreForEqualCheck { /* tagging only */ }
通過使用
pClass.getFields()和/或pClass.getDeclaredFields()物件的類,使用反射來分析要比較的物件。這甚至可能是不同的類。迭代所有未標記為忽略的欄位,比較值。
優化
為了從上面擴展黑名單,還引入白名單:還創建一個注釋
UseForEqualCheck以僅檢查這些欄位。為了提高速度,在分析相應的類及其欄位時,您可以創建要檢查的欄位的可迭代串列,而不是每次都進行反射欄位分析,只需使用串列即可。
通常,您會
equals()在檢測到的欄位值上使用。您還可以 a) 使用另一個自定義注釋標記類,或 b) 檢查任何白名單/黑名單注釋的欄位,以便您可靠地將新方法用于嵌入/繼承/委托的注釋類。
警告
與所有反射一樣,在分析在編譯程序 (javac) 中被注釋前處理器或位元組碼編織修改的類的層次結構時,您可能會遇到麻煩。這主要是指 Java EE aka Jakarta,但也可能發生在代碼中包含幕后功能的任何地方,或者運行時行為發生變化的地方,例如注入、面向方面的庫等。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/395742.html
