0

I want to return an "Relation" using the default method "negate()", which always returns the opposite of the method test(). How can I do that?

public interface Relation<X,Y> {

    boolean test(X x, Y y);

    default Relation<X,Y> negate() {
        // TODO
        Relation<X, Y> relation = new Relation<X, Y>() {

            public boolean test(X x, Y y) {
                return !this.test(x, y);
            }
            
        };
        return relation;
    }
}

I tried this code however it gives me stack overflow error

Turing85
  • 18,217
  • 7
  • 33
  • 58

1 Answers1

2

Since Relation in its current form is a functional interface, we can return a lambda from negate() that inverts the result of test(...):

public interface Relation<X, Y> {
    ...

    default Relation<X, Y> negate() {
        return (x, y) -> !this.test(x, y);
    }
    ...
}

Ideone demo

Turing85
  • 18,217
  • 7
  • 33
  • 58
  • Thanks, is there a way doing this without using lamda expression? – trollinator Sep 03 '20 at 20:05
  • 1
    You can always transform a lambda into an anonymous class: [`return new Relation() { public boolean test(X x, Y y) { return !Relation.this.test(x, y); } };`](https://ideone.com/uDMV6g) – Turing85 Sep 03 '20 at 20:08
  • Thank you very much, but the part "Relation.this.test(x, y)" confuses me, why do I need to write "Relation" before this? – trollinator Sep 03 '20 at 20:16
  • Is that somehow because I am in a inner class and I want to access the method of the outer class? – trollinator Sep 03 '20 at 20:17
  • 1
    Yes. See [this post and its answers](https://stackoverflow.com/questions/1816458/getting-hold-of-the-outer-class-object-from-the-inner-class-object). – Turing85 Sep 03 '20 at 20:19