class Foo
{
int x;
int y;
int z;
//Overriding equals() and hashCode() to just field x
}
List<Foo> myList=new ArrayList<Foo>();
myList.add(fooObj);
myList.add(fooObj2);
我的所有 Foo 对象基本上都是根据字段x进行比较的。
我想基于值x从列表中获取 fooObj 。为什么添加一个方法get(Object o)
而不是在执行list.get(list.indexOf(fooObj))
以从列表中获取完整对象时没有意义。 indexOf()
可以返回“ null ”,因此需要进行空检查,这也不好。
更新:
使用getX()的关键值对来映射是一个好主意 - &gt; objFoo。如果我的Foo由两个字段定义,例如Foo类的X和Y,则 Map不能用于此目的。
答案 0 :(得分:1)
您可以改为使用Map<Foo, Foo>
:
Map<Foo, Foo> map = new HashMap<Foo, Foo>();
// Store
map.put(fooObj, fooObj);
// Retrieve
map.get(fooObj2); // => fooObj
虽然我认为覆盖equals
对于这个用例来说不是一个很好的解决方案。您的equals
覆盖会将fooObj
和fooObj2
视为“相等”,但您的应用程序希望它们在某些地方被视为不同。这些冲突迟早会反击,引入错误并让你头疼。
我宁愿将标识符与数据分开,并为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
或@EmbeddedId
来Foo
个FooKey
实体。这可能与您当前的场景无关,但如果您考虑将来某个时候实现持久性,您可能已经开始在类层次结构中考虑这一点。
答案 1 :(得分:0)
list.get(list.indexOf(fooObj))
不是解决方法,而是List
类的设计方式。如果您希望通过从List
类继承,添加方法并使用新类型而不是{{}来可以 添加 get(Object) 1}}。但这似乎为这么小的好处做了很多工作。