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を取得したいと思います。リストから完全なオブジェクトを取得するためにget(Object o)回避策を実行する代わりに、メソッドを追加するのが意味をなさないのはなぜですか。「 null 」を返す可能性があるため、nullチェックが必要ですが、これも良くありません。list.get(list.indexOf(fooObj))indexOf()

更新

Map は、getX() -> objFoo のキーと値のペアを持つことをお勧めします。私の Foo が Foo クラスの X と Y という 2 つのフィールドで定義されている場合、この目的で Map を使用することはできません。

4

2 に答える 2

1

Map<Foo, Foo>代わりにa を使用できます。

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

equalsこのユースケースでは、オーバーライドはあまり良い解決策ではないと思いますが。オーバーライドはと「等しい」としてequals扱いますが、アプリケーションはそれらをどこかで異なるものとして扱うことを望んでいます。これらの競合は遅かれ早かれ裏目に出て、バグを引き起こし、頭痛の種になります。fooObjfooObj2

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@EmbeddedIdを使用してFooエンティティをFooKeys で識別できます。これは現在のシナリオには関係ないかもしれませんが、将来永続化を実装することを考えている場合は、クラス階層でこれを検討し始めたいと思うでしょう。

于 2013-06-07T20:14:56.887 に答える