【发布时间】:2016-07-12 01:14:00
【问题描述】:
使用list.contains(someObject)时是否可以在本地覆盖Object#equals(Object)?
示例:
class SomeObject {
...
private int id;
private String name;
@Overrdide
public boolean equals(Object other){
...
return this.id == other.id;
}
}
但是,如果我在使用list.contains(someObject) 时想要另一种等于怎么办?例如,我想知道列表是否包含某个名称?是否可以“匿名”覆盖Object#equals(Object)?
更具体的解释为什么我需要它:
int objectId = ... // Some event which passes me the attribute of an object but not the object itself
现在我有了List<SomeObject> someObjects,我想知道这个列表是否包含一个带有objectId 的对象,而不必对其进行迭代。
我能想到的一个“解决方案”是使用Map<Integer, SomeObject> mapping,然后使用someObject = mapping.get(objectId)
编辑:我的问题不是重复的,因为我特别要求覆盖Object#equals(Object)。
【问题讨论】:
-
应该是这样,但恕我直言,这是集合 API 最糟糕的事情。您可以在许多地方使用自定义 Comparator,但您只能使用
equals的一个概念。 -
如果 Java 只有 case-classes :-(
-
使用比较器指定相等性适用于 Set 和 Map 键(但它会损害性能 - 操作变为 O(log n),因为您必须使用 TreeMap 而不是 HashMap)。但它对 List 没有帮助。应该可以通过
indexOf、contains等方法使用自定义的相等概念,但如果不创建包装类并根据需要覆盖 equals 是不可能的。这很烦人。 -
@SklogW 列表有多大?如果您对顺序不感兴趣并且多次查询一个属性,您可以使用特定于该属性的比较器重新排序列表,然后检查
Collections.binarySearch(list, cmp) >= 0 -
不是重复的,因为我专门询问是否覆盖 equals()。恕我直言,重复是隐含的。