假設我有一個使用lambda表達式(閉包)定義的對象列表。有沒有辦法檢查它們,以便比較它們?有沒有辦法比較lambdas?
我最感興趣的代碼是
List<Strategy> strategies = getStrategies();
Strategy a = (Strategy) this::a;
if (strategies.contains(a)) { // ...
完整的代碼
import java.util.Arrays;
import java.util.List;
public class ClosureEqualsMain {
interface Strategy {
void invoke(/*args*/);
default boolean equals(Object o) { // doesn't compile
return Closures.equals(this, o);
}
}
public void a() { }
public void b() { }
public void c() { }
public List<Strategy> getStrategies() {
return Arrays.asList(this::a, this::b, this::c);
}
private void testStrategies() {
List<Strategy> strategies = getStrategies();
System.out.println(strategies);
Strategy a = (Strategy) this::a;
// prints false
System.out.println("strategies.contains(this::a) is " + strategies.contains(a));
}
public static void main(String... ignored) {
new ClosureEqualsMain().testStrategies();
}
enum Closures {;
public static <Closure> boolean equals(Closure c1, Closure c2) {
// This doesn't compare the contents
// like others immutables e.g. String
return c1.equals(c2);
}
public static <Closure> int hashCode(Closure c) {
return // a hashCode which can detect duplicates for a Set<Strategy>
}
public static <Closure> String asString(Closure c) {
return // something better than Object.toString();
}
}
public String toString() {
return "my-ClosureEqualsMain";
}
}
這樣看來,唯一的解決辦法是定義每個lambda作爲一個字段,只使用這些字段。如果您想打印出所調用的方法,最好使用Method
。用lambda表達式有更好的方法嗎?
另外,是否可以打印一個lambda並獲得一些人類可讀的東西?如果您打印this::a
,而不是
ClosureEqualsMain$$Lambda$1/[email protected]
得到類似
ClosureEqualsMain.a()
甚至使用this.toString
和方法。
my-ClosureEqualsMain.a();
您可以在閉包中定義toString,equals和hashhCode方法。 –
@AnkitZalani你可以給一個編譯的例子嗎? –
@PeterLawrey,由於在Object中定義了toString,所以我認爲你可以定義一個接口來提供'toString'的默認實現,而不會違反* single-method *接口的功能。我沒有檢查過這個。 –