I am wondering what may be a good way of implementing some kind of observable in Java without much interface-stuff.
I thought it would be nice to use the predefined functional interfaces. For this example, I use a String Consumer to represent a listener that takes a String for notification.
class Subject {
List<Consumer<String>> listeners = new ArrayList<>();
void addListener(Consumer<String> listener) { listeners.add(listener); }
void removeListener(Consumer<String> listener { listeners.remove(listener); }
...
}
class PrintListener {
public void print(String s) { System.out.println(s); }
}
Subject subject = new ...
PrintListener printListener = new ...
subject.add(printListener); // Works, I find it in the listener list
subject.remove(printListener); // Does NOT work. I still find it in the list
I found the explanation:
Consumer<String> a = printListener::print;
Consumer<String> b = printListener::print;
// it holds:
// a==b : false
// a==a : true
// a.equals(b): false
// a.equals(a): true
So I can't use lambdas/function pointers as they are.
There is always the alternative to have the good old interfaces back, s.t. we register object instances but not lambdas. But i hoped there is something more lightweight.
EDIT:
From current responses, I see the following approaches:
a) Return a Handle that holds the original reference
b) store the original reference yourself
c) Return some ID (integer) that can be used in subject.remove() instead of the original reference
I tend to like a). You still have to keep track of the Handle.