Dire che ho un elenco di oggetti che sono stati definiti utilizzando espressioni lambda (chiusure). C'è un modo per controllarli in modo che possano essere confrontati?C'è un modo per confrontare i lambda?
Il codice mi interessa di più è
List<Strategy> strategies = getStrategies();
Strategy a = (Strategy) this::a;
if (strategies.contains(a)) { // ...
Il codice completo è
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";
}
}
sembrerebbe l'unica soluzione è quella di definire ogni lambda come un campo e utilizzare solo quei campi. Se si desidera stampare il metodo chiamato, è meglio usare Method
. C'è un modo migliore con espressioni lambda?
Inoltre, è possibile stampare un lambda e ottenere qualcosa di leggibile dall'uomo? Se si stampa this::a
invece di
ClosureEqualsMain$$Lambda$1/[email protected]
ottenere qualcosa di simile
ClosureEqualsMain.a()
o anche utilizzare this.toString
e il metodo.
my-ClosureEqualsMain.a();
È possibile definire i metodi toString, equals e hashhCode all'interno della chiusura. –
@AnkitZalani Puoi fare un esempio che compila? –
@PeterLawrey, Poiché 'toString' è definito su' Object', penso che sia possibile definire un'interfaccia che fornisce un'implementazione predefinita di 'toString' senza violare il requisito * a metodo singolo * per le interfacce funzionali. Non ho controllato questo però. –