0

我有

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 还是可以创建我正在尝试的东西?欢迎任何建议或意见。提前致谢

4

3 回答 3

2

经过一番思考,您要做的是将地图从类中键出来,而不是实例....

HashMap<Class<? extends Module>, <Module>> mymap = .....

然后,每个类类型只有一个值。你可以放:

mymap.put(module.class(), module);
于 2013-05-03T17:59:39.060 回答
1

怎么样:

return getClass().getName().hashCode();

虽然,你可以很容易地使用:

return getClass().hashCode();
于 2013-05-03T17:56:27.017 回答
1

您可以像下面这样简单地实现它:

@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>. 每个模块实现都会将自己添加到您的注册表中,如果模块的类已经在映射中,您只需拒绝或忽略新的模块实例。

于 2013-05-03T17:58:07.623 回答