我有
interface Module {
List<String> parse();
}
该接口有几种实现,在应用程序中,我希望有一个HashSet<Module>
,确保每个模块只有一个实例。为此,我需要一个适当的hashCode
为每个类。hashCode
的正确实现应该是对一个模块类的不同实例返回相同的常量,但对不同的模块返回不同的常量。
要创建一个很好的设计解决方案,我想从模块的名称中计算hashCode,如:
public int hashCode() {
return ConcreteModule.class.getName().hashCode();
}
但是这段代码对于每个接口的实现都是一样的…我的想法是创建一个实现哈希码的抽象模块,但是有可能达到扩展这个抽象类的类的名称吗?如:
public abstract class AbstractModule implements Module {
public int hashCode() {
// get the class name of class extending the abstract module
// and return hashcode of its string name
}
}
然后
public class ConcreteModule extends AbstractModule implements Module {
// implementation of parse() no need to create hashcode for each module
}
您是否建议为每个模块创建hashCodes,或者有可能创建我正在尝试的东西?欢迎提出任何建议或意见。提前感谢
经过一番思考后,您想要做的是将映射键从类中取出,而不是从实例中取出....
HashMap<Class<? extends Module>, <Module>> mymap = .....
那么每个类类型只有一个值。你可以输入:
mymap.put(module.class(), module);
您可以像下面这样简单地实现它:
@Override
public final int hashCode() {
return this.getClass().getName().hashCode();
}
@Override
public final boolean equals(Object other) {
if (other == this) {
return true;
}
if (other == null) {
return false;
}
return other.getClass().equals(this.getClass());
}
但我不确定这是不是最好的主意。而且,你不能保证接口的所有实现都扩展了你的抽象类。
您可以简单地维护一个Map<Class<? extends Module>, Module>
。每个模块实现都会将自己添加到注册表中,如果模块的类已经在映射中,则只需拒绝或忽略新的模块实例。
如何:
return getClass().getName().hashCode();
不过,你也可以简单地使用:
return getClass().hashCode();