Java 如何从集合中返回对象。 class-Foo { int x; int-y; intz; //将equals()和hashCode()重写为仅为字段x } List myList=new ArrayList(); myList.add(fooObj); myList.add(fooObj2);
我所有的Foo对象基本上都是基于字段x进行比较的 我想根据值x从列表中获取fooObj。为什么添加一个方法(比如Java 如何从集合中返回对象。 class-Foo { int x; int-y; intz; //将equals()和hashCode()重写为仅为字段x } List myList=new ArrayList(); myList.add(fooObj); myList.add(fooObj2);,java,list,collections,Java,List,Collections,我所有的Foo对象基本上都是基于字段x进行比较的 我想根据值x从列表中获取fooObj。为什么添加一个方法(比如get(Object o))而不是执行list.get(list.indexOf(fooObj))从列表中获取完整的对象是没有意义的indexOf()可以返回“null”,因此需要进行null检查,这也不好 更新: Map最好有一个getX()->objFoo的键值对。如果我的Foo是由两个字段定义的,比如Foo类的X和Y,那么Map就不能用于此目的。list.get(list.ind
get(Object o)
)而不是执行list.get(list.indexOf(fooObj))
从列表中获取完整的对象是没有意义的indexOf()
可以返回“null”,因此需要进行null检查,这也不好
更新:
Map最好有一个getX()->objFoo的键值对。如果我的Foo是由两个字段定义的,比如Foo类的X和Y,那么Map就不能用于此目的。
list.get(list.indexOf(fooObj))
不是一个解决方法,它只是list
类的设计方法。如果愿意,可以通过从列表
类继承、添加方法并使用新类型而不是列表
来添加get(对象)。但是为了这么小的好处,这似乎需要做很多工作。您可以使用地图来代替:
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);
然后,您的应用程序代码变得更容易理解:
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 Map=newarraylist();
//贮藏
Foo fooObj=新Foo(新FooKey(123));
map.put(fooObj.id,fooObj);
//取回
map.get(fooObj.id);//=>fooObj
map.get(新FooKey(123));//如果FooKey.equals被正确重写,也可以使用fooObj
当您决定将Foo
对象持久化到数据库中时,使用单独的(复合)键字段也可以证明是有价值的。例如,JPA允许您使用@IdClass
或@EmbeddedId
来让Foo
实体通过FooKey
标识。这可能与您当前的场景无关,但如果您打算在将来某个时候实现持久化,您可能希望已经开始在类层次结构中考虑这一点。在这种情况下,您能推荐从列表中获取元素的最佳方法吗?是的,就是您这样做的。使用indexOf,然后使用get(index).Yup。每次都需要执行空检查:(@javafander是的……在列表类的Javadoc中确实如此。但不用担心,每个人都会犯这些错误,它真的永远不会结束,但它会变得更好。如果你发现自己想要以这种方式检索对象(基本上使用Foo的部分实例作为检索存储实例的键)你可能会建议考虑查看一个关键的集合——比如“代码> SET/<代码> SET,更糟糕的是,你甚至不能得到一个对象,比如使用索引()方法来完成列表,然后应用一个GET())。为什么你不能创建一个包含Y和Z的对对象并将其存储在地图中?“如果我的Foo由两个字段定义,比如Foo类的X和Y,那么Map不能用于此目的。“当然可以,您只需要用这两个字段创建一个键类型,这可能比其他字段更简洁。indexOf
不能返回null
,因为基元类型不是对象。如果它不包含元素,则将其传递给get(int)
将导致出现索引自动边界异常
。感谢您的解决方案。我觉得Java API应该在其列表实现中包含此类内容。@Java爱好者这不是列表
的工作,在我看来,任何类都不需要这样做。如果您说fooObj.equals(fooObj2)
是正确的,如果fooObj.x==fooObj2.x
,那么您应该期望其他类将它们视为平等的。许多类依赖于此,如果您试图强加自己的规则,则无法保证事情会按预期进行。
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