您可以使用 aMap<Foo, Foo>
代替:
Map<Foo, Foo> map = new HashMap<Foo, Foo>();
// Store
map.put(fooObj, fooObj);
// Retrieve
map.get(fooObj2); // => fooObj
虽然我认为覆盖equals
对于这个用例来说不是一个很好的解决方案。您的equals
覆盖将fooObj
andfooObj2
视为“相等”,但您的应用程序希望它们在某些地方被视为不同。这些冲突迟早会适得其反,引入错误并让您头疼。
我宁愿将标识符与数据分开并给出Foo
一个FooKey
字段。
class FooKey {
final int x;
public FooKey(int x) {
this.x = x;
}
// TODO Override equals and hashCode to only compare FooKeys on x field
}
class Foo {
final FooKey id;
int y;
int z;
public Foo(FooKey id) {
this.id = id;
}
}
然后,您的应用程序代码变得更容易理解:
Map<FooKey, Foo> map = new ArrayList<FooKey, Foo>();
// Store
Foo fooObj = new Foo(new FooKey(123));
map.put(fooObj.id, fooObj);
// Retrieve
map.get(fooObj.id); // => fooObj
map.get(new FooKey(123)); // also fooObj if FooKey.equals is properly overridden
当您决定要将Foo
对象持久保存在数据库中时,使用单独的(复合)键字段也可以证明是有价值的。例如,JPA 允许您使用@IdClass
or@EmbeddedId
让Foo
实体由FooKey
s 标识。这可能与您当前的场景无关,但如果您正在考虑在未来某个时间实现持久性,您可能希望已经开始在您的类层次结构中考虑这一点。