来自反射的哈希码



我有

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();

相关内容

  • 没有找到相关文章

最新更新