簡體   English   中英

我們可以動態更改equals方法的行為嗎?

[英]Can we change behavior of equals method dynamically?

我有一類有兩個名為xy變量。 在此類中,我重寫了equalshashCode方法來比較此類的兩個對象。 但是我們的要求是有時基於x有時基於y比較此類的兩個對象。 用Java動態地可以嗎?

編輯:我還有一個名為B的類,在這個類中有兩個方法m1和m2,我想比較上面的類對象,當我們從m1調用(進行排序)時,將比較上面的對象基於x(通過比較x變量表示比較對象),當我們從m2調用(進行排序)時,我們根據y進行比較。

可以基於最后一個方法更改行為以調用您的方法,但是出於很多原因,您不應該這樣做。

  • 它違反了等價合約,因此破壞了旨在處理集合的幾種算法的功能
  • 不知道調用者就無法知道比較的結果,這是一個容易打破的硬依賴關系

但是,如果您堅持需要,那么您可以喜歡

StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
if (stackTraceElements.length < 3)
{
    // do something when last method to call is not available
    // probably you'll want to return something
}
String callerMethod = stackTraceElements[2].getMethodName();
if (callerMethod.equals("m1"))
{
    // something
} else
{
    // something else
}

此示例得到了簡化,因為它假定調用此方法的方法是候選方法-它可以是調用堆棧之后的某些方法。

如前所述,不建議這樣做。 而是為此目的使用不同種類的比較器,並為排序方法提供相關的比較器,以使每個上下文具有不同種類的排序。

根據比較的復雜程度,您可以在該類中執行此操作,也可以使用兩個單獨的比較器類。

public boolean equals(Object other){
    if(condition == true){
        return x==x;
    }else{
        return y==y;
    }
}

要么

public boolean equals(Object other){
    if(condition == true){
        return new CompareX(this, other).compare();
    }else{
        return new CompareY(this, other).compare();
    }
}

當然,您必須將比較邏輯擴展到有效的邏輯。

哦,同樣的原理適用於hashCode。

動態更改equals的行為是不可能的。 您必須使用Comparator從類外部提供比較。

由於Java8與Lambdas一起使用,因此Comparators器易於使用。

有一種comparing方法。 您可以在要比較的方法中創建比較器。

// A comparator comparing on x
Comparator<A> comp1 = comparing (a -> a.x); 
// A comparator comparing on the output of m1
Comparator<A> comp2 = comparing (A::m1);
// A comparator comparing on the output of m1 and when equals, comparing on x
Comparator<A> comp2 = comparing (A::m1).thenComparing (a -> a.x);

從外部可以確定使用哪個比較器。

還有一種在Java8中對數據進行排序的新方法:

List<A> data;
data.stream ().sorted (comparing (a -> a.x));

當然,必須允許您為此使用Java8。

如果可以將標記設置代碼添加到m1和m2,則可以修改eis答案以擺脫kludgy stacktrace的內容。

它仍然很混亂。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM