我想使用indexOf
,但List
中的对象不是相等的对象,但是它们具有值相等(即它们等同但不相等)。
我想以与indexOf
方法不同的方式进行Object.equals
比较。我正在考虑覆盖equals方法以使用我的isEquivalent方法,但我不确定如何做到这一点,如果它甚至可能。
我尝试了很多这方面的变化,但不断出错:
List<CustomType> items{
@Override
public boolean equals(Object o)
{
return false;
}
}
= //stuff to populate it
我也看过this answer他们在谈论EqualityComparer的时候在java中有类似的内容吗?
或者还有其他方法可以实现这个目标吗?
答案 0 :(得分:3)
在我看来,缺少像EqualityComparer
这样的东西是关于标准java的最糟糕的事情之一。这意味着如果您想要使用ArrayList
或HashSet
等集合中的对象,那么indexOf
和{{1}等方法只会遇到一个相等概念}。这非常非常烦人。它与contains
形成鲜明对比,后者更加灵活,允许您使用TreeSet
指定Comparator
所需的顺序。
我建议不要压倒Set
来表示与人们期望的不同的东西。这可能会导致错误和混乱。此外,您可能希望能够在某些时候使用具有通常含义的indexOf
。
相反,您可以编写自己的indexOf
界面
EqualityComparer
然后你可以像这样写一个静态方法public interface EqualityComparer<E> {
boolean areEqual(E e1, E e2);
int hash(E e); // Not needed for indexOf, but very useful in general
}
:
indexOf
答案 1 :(得分:2)
这是我对它的抨击。我使用ArrayList
因为List是一个接口,你需要覆盖所有方法。
List<CustomType> customList = new ArrayList<CustomType>() {
@Override
public int indexOf(Object o) {
if (o instanceof CustomType) {
for (int i = 0; i < this.size(); i++) {
CustomType c = (CustomType) o;
if (c.isEquivalent(this.get(i))) {
return i;
}
}
}
return -1;
}
};
// use indexOf like normal, but beware of side-effects as mentioned in the comments
我之前在评论中试图说的是,如果覆盖List.equals
,则意味着您要将List
对象与另一个对象进行比较,而不是列表中的对象。要做你想要的,你需要这样做。
class CustomType {
public boolean isEquivalent(CustomType ct) {
return true; // TODO: Implement this
}
@Override
public boolean equals(Object obj) {
// TODO: Implement this
if (obj instanceof CustomType) {
return this.isEquivalent((CustomType) obj);
}
return false;
}
@Override
public int hashCode() {
return super.hashCode(); // TODO: Implement this
}
}
public static void main(String args[]) {
List<CustomType> lst = new ArrayList<CustomType>();
// use indexOf like normal
}
答案 2 :(得分:0)
在自定义对象中覆盖equals()和hashcode()。如果两个对象相等,则它们的哈希码也应该相等。