Search code examples
javaclass-design

Implementing bidirectional relations between objects of the same class


I have to implement a class whose instances have a bidirectional relation to each other. For example I have the class FooBar which should offer the method sameAs(FooBar x) and maintain a Set for each instances containing its equivalent instances. So if I call foo.sameAs(bar), the Set in foo should contain bar and vice versa. Invoking bar.sameAs(foo) doesn't work, of course.

For clarifiction: the instances of this class are only semantically equal. equals should still return false.

The solutions I've come up with is either to implement a private method internalSameAs(FooBar x) which is invoked from sameAs(FooBar x) or to use a static method sameAs(FooBar x, FooBar y).

Solution 1:

class FooBar {
    Set<FooBar> sameAs = new HashSet<FooBar>();

    public void sameAs(FooBar x) {
        this.internalSameAs(x);
            x.internalSameAs(this);
        }

        public void internalSameAs(FooBar x) {
            sameAs.add(x);
        }
    }

Solution 2:

class FooBar {
    Set<FooBar> sameAs = new HashSet<FooBar>();

    public static void sameAs(FooBar x, FooBar y) {
        x.sameAs.add(y);
        y.sameAs.add(x);
    }
}

Which one would you prefer and why? Or is there another way I didn't think about?


Solution

  • are you flexible with the data structures to be used? If so you could use a Multimap (from Guava Collections) that is static amongst all the instances of the class FooBar. In that Multimap you can have the keys as FooBar references (or a unique id if you have one) and the values would be the references (or id.s) of the FooBars that have the sameAs relation.