0
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 。为什么添加方法 sayget(Object o)而不是解决方法 alist.get(list.indexOf(fooObj))从列表中获取完整对象是没有意义的。indexOf()可以返回“ null ”,因此需要进行空检查,这也不好。

更新

Map 最好有一个 getX() -> objFoo 的键值对。如果我的 Foo 由 Foo 类的 X 和 Y 两个字段定义,则Map 不能用于此目的。

4

2 回答 2

1

您可以使用 aMap<Foo, Foo>代替:

Map<Foo, Foo> map = new HashMap<Foo, Foo>();
// Store
map.put(fooObj, fooObj);
// Retrieve
map.get(fooObj2); // => fooObj

虽然我认为覆盖equals对于这个用例来说不是一个很好的解决方案。您的equals覆盖将fooObjandfooObj2视为“相等”,但您的应用程序希望它们在某些地方被视为不同。这些冲突迟早会适得其反,引入错误并让您头疼。

我宁愿将标识符与数据分开并给出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 允许您使用@IdClassor@EmbeddedIdFoo实体由FooKeys 标识。这可能与您当前的场景无关,但如果您正在考虑在未来某个时间实现持久性,您可能希望已经开始在您的类层次结构中考虑这一点。

于 2013-06-07T20:14:56.887 回答
0

list.get(list.indexOf(fooObj))不是一种解决方法,它只是List类的设计方式。如果您愿意,可以通过从类继承添加方法List并使用新类型而不是List. 但为了这么小的利益,这似乎需要做很多工作。

于 2013-06-07T19:22:14.037 回答