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?
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 FooBar
s that have the sameAs
relation.