1

我正在尝试HashMap使用CircuitId class. CircuitId 类包含一个 String clci 成员,并且该类hashCode()/equals()基本上使用 clci 成员的hashCode()/equals().

我想这样做,以便我可以使用简单的字符串来查找地图,而无需将字符串转换为CircuitId对象来查找地图。但它不起作用,我认为因为HashMap使用这种评估形式(key==null ? k==null : key.equals(k)),其中 key 是输入键,k 是地图中的键条目,特别是 key.equals(k) 部分。我想知道为什么 HashMap 没有这样做k.equals(key)

(至少这样,我认为我正在尝试做的事情会奏效。)但事实并非如此,这样做有诀窍吗?

4

3 回答 3

2

如果我用检查覆盖了 equals() 以处理传递的键是字符串还是实际的 CircuitId 对象,我不明白为什么它不起作用。

容器是否将电路与字符串进行比较,或者字符串与电路进行比较是特定于实现的,并且不保证在 JRE 的未来版本中相同。

通常,给定两个对象ab,预计a.equals(b)何时出现b.equals(a),反之亦然。这称为对称属性。

在 and 的情况下CircuitIdString虽然您可以覆盖CircuitId.equals()circuit.equals(id)返回true,但id.equals(circuit)始终是false因为您无法覆盖String.equals()

您应该使用 a Map<String,CircuitId>(Map<CircuitId,SomethingElse>如果您需要将其CircuitId作为另一个地图中的键,则可能使用另一个。

于 2013-03-01T19:58:17.477 回答
0

如果您想通过 查找条目String,您应该使用 aHashMap<String, CircuitID>或类似的东西。

如果你想要两者,你可能想要有两个地图,或者做两级查找:

CircuitId circ = knownCircuits.get(stringKey);
if (circ != null) {
     return otherMap.get(circ);
} else {
     return null;
}
于 2013-03-01T19:56:30.907 回答
0

使用 CircuitId 键控映射,但覆盖 的get()方法,HashMap因此它也适用于String对象:

Map<CircuitId, CircuitLayout> map = new HashMap<CircuitId, CircuitLayout>() {
    @Override
    public CircuitLayout get(Object key) {
        if (key instanceof String)
            return super.get(new CircuitId((String)key));
        return super.get(key);
    }
}

您可以类似地覆盖contains()和您需要的任何其他方法。

这样做的好处是您不必通过使它们与其他类“相等”的实例来“破坏”您的类。它将任何“丑陋”隐藏在一个(和正确的)地方。

于 2013-03-01T20:10:45.823 回答