有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从集合返回对象。

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);

所有myFoo对象基本上都是基于字段x进行比较的

我想根据值x从列表中获取fooObj。为什么添加一个方法(比如get(Object o))而不是通过list.get(list.indexOf(fooObj))从列表中获取完整的对象是没有意义的indexOf()可以返回“null”,因此需要进行null检查,这也不好

更新

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


共 (2) 个答案

  1. # 1 楼答案

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

    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允许您使用@IdClass@EmbeddedId来让Foo实体由FooKey标识。这可能与您当前的场景无关,但如果您考虑在将来某个时候实现持久性,您可能希望已经开始在类层次结构中考虑这一点

  2. # 2 楼答案

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