I'm assuming the key type on your TreeMap was meant to be a Class, not a MyContainedObject.
If you actually need to listen for ChangeEvents on specific class types, and you want to be able to add elements to your collection even after setting listeners, this seems pretty reasonable. You'll probably want to support multiple listeners for the same type, so you should either use a Multimap class (Google Collections has some) or use a collection (probably an IdentityHashSet) for the values in your Map.
You may also want to add a type parameter to ChangeListener so that the listener can get the object the event fired on already casted to the appropriate type.
interface ChangeListener<T> {
void changed(T obj, /* whatever */);
}
You'll have to do an unchecked cast inside of your container for this to work, but it should be safe as long as your listener adding method does the right thing. eg:
public <T extends MyContainedObject> addChangeListener(Class<T> klass,
ChangeListener<? super T> listener) {
...
}
private <T extends MyContainedObject> Set<ChangeListener<? super T>> getChangeListeners(T obj) {
Set<ChangeListener<? super T>> result = new IdentityHashSet<ChangeListener<? super T>>();
for (Map.Entry<Class<? extends MyContainedObject>, Set<ChangeListener<?>>> entry : listeners.entrySet()) {
if (entry.getKey().isInstance(obj)) {
// safe because signature of addChangeListener guarantees type match
@SuppressWarnings("unchecked")
Set<ChangeListener<? super T>> listeners =
(Set<ChangeListener<? super T>>) entry.getValue();
result.addAll(listeners);
}
}
return result;
}
One minor nit: I'd avoid using "className" as the name of a variable that holds a Class object. A class name is a String, typically the result of Class.getName(), etc.. It's a bit annoying, but the convention I've usually seen to avoid get around the fact that "class" is a reserved word is to misspell it as either "klass" or "cls".
Also, if you don't need the ability to update your collection after adding listeners then I'd go with what akf suggested, as it's simpler.