我正在研究化学包,我有一个列出周期表中所有元素的类。理想情况下,元素将成为Java枚举的一部分。不幸的是,我还需要一个用作通配符的元素:每个其他元素应等于该元素。 Java不允许覆盖枚举的equals()方法,否则我会这样做。是否有人能够为我刚才描述的情况提出合理的设计模式?
编辑:感谢您的贡献。我确实没有注意到 equals()所需的传递属性。
元素周期表的元素将被分配给图形结构上的不同节点(在数学意义上)。给定此图结构,然后我在原始图中查找特定子图结构的所有嵌入(子图同构问题)。子图结构的期望属性是具有分配了通配符的某些节点,以便我可以将这些节点映射到原始图中的任何节点,而不管分配给它的元素如何。这就是为什么我正在寻找一种非传递关系,使得通配符可以等于两个不同的元素而不暗示元素本身是相等的。我当前的算法使用泛型并调用 equals()来检查两个节点中的元素是否相等。
答案 0 :(得分:1)
正如mystarrocks指出的那样,你的设计存在的一大问题是它违反了等于合同。具体来说,根据类Object
中的规范,equals方法应该:
equals方法在非null对象引用上实现等价关系:
- 它是自反的:对于任何非空引用值x,x.equals(x)应该返回true。
- 它是对称的:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true。
- 它是传递性的:对于任何非空引用值x,y和z,如果x.equals(y)返回true而y.equals(z)返回true,则x.equals(z)应返回true
- 它是一致的:对于任何非空引用值x和y,x.equals(y)的多次调用始终返回true或始终返回false,前提是没有修改在对象上的equals比较中使用的信息。
- 对于任何非空引用值x,x.equals(null)应返回false。
您的设计会违反传递财产。如果钠等于通配符,而通配符等于钾,则钠必须等于钾。
更好的方法是创建一个帮助器等于方法,以便查看两个元素是否可以认为相等(不同于等于)。通配符只是真正等于通配符,但可以认为它等于任何元素。
public enum Element {
HYDROGEN,
HELIUM,
SODIUM,
//.....
URANIUM,
WILD_CARD;
public boolean consideredEqual(Object other) {
if (other == null || ! (other instanceof Element)) return false;
Element e = (Element) other;
if (this.equals(Element.WILD_CARD) || e.equals(Element.WILD_CARD)) return true;
return equals(other);
}
}