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”,因此需要进行 null 检查,这也不好。
更新:
Map 最好有一个 getX() -> objFoo 的键值对。如果我的 Foo 由 Foo 类的两个字段(例如 X 和 Y)定义,则 Map 不能用于此目的。
最佳答案
您可以使用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
时,使用单独的(复合)键字段也很有值(value)。数据库中的对象。例如,JPA 允许您使用 @IdClass
或@EmbeddedId
让Foo
实体由 FooKey
标识s。这可能与您当前的场景无关,但如果您考虑在将来某个时候实现持久性,您可能希望已经开始在类层次结构中考虑这一点。
关于java - 如何从集合中返回对象。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16991424/