我正在尝试使用HashMap
键入CircuitId class
。 CircuitId类包含一个String clci成员,该类基本上使用clci成员的hashCode()/equals()
覆盖hashCode()/equals()
。
我想这样做,以便我可以使用简单的字符串查找地图,并取消将字符串转换为CircuitId
对象以查找地图。但它不起作用,我认为因为HashMap
使用这个评估形式(key==null ? k==null : key.equals(k))
,其中key是输入键,k是映射中的键条目,特别是key.equals(k)部分。我想知道为什么HashMap没有代替k.equals(key)
?
(至少那样,我认为我想要做的事情会起作用。)但事实并非如此,是否有诀窍呢?
答案 0 :(得分:2)
如果我使用检查来覆盖equals()以处理传递的密钥是字符串还是实际的CircuitId对象,我不明白为什么它不起作用。
容器是否将电路与字符串进行比较,或者电路中的字符串是否是特定于实现的,并且在将来的JRE版本中不保证它是相同的。
通常,给定两个对象a
和b
,a.equals(b)
时b.equals(a)
,CircuitId
反之亦然。这称为对称属性。
如果是String
和CircuitId.equals()
,您可以覆盖circuit.equals(id)
并让true
返回id.equals(circuit)
,false
将永远是String.equals()
,因为您无法覆盖Map<String,CircuitId>
。
如果您需要Map<CircuitId,SomethingElse>
作为其他地图中的关键字,您应该使用CircuitId
(或许可能使用其他{{1}}。
答案 1 :(得分:0)
如果您想按String
查找条目,则应该使用HashMap<String, CircuitID>
或类似的内容。
如果你想要两者,你可能想要有两张地图,或者进行两级查找:
CircuitId circ = knownCircuits.get(stringKey);
if (circ != null) {
return otherMap.get(circ);
} else {
return null;
}
答案 2 :(得分:0)
使用CircuitId键控映射,但覆盖get()
的{{1}}方法,以便它也适用于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);
}
}
以及您需要的任何其他方法。
这样做的好处是,您不必通过使其与其他其他类成为“相等”的实例来“破坏”您的类。它将任何“丑陋”隐藏在一个(和右)的位置。