有没有办法覆盖equals
数据类型使用的Set
方法?我为一个名为equals
的类编写了一个自定义Fee
方法。现在我有一个LnkedList
Fee
,我想确保没有重复的条目。因此,我正在考虑使用Set
LinkedList
equals
,但决定两项费用是否相等的标准存在于Fee
类的重写LinkedList
方法中。< / p>
如果使用equals
,我将不得不遍历每个列表项并在Fee
类中调用覆盖Set
方法,其余条目作为参数。仅仅阅读这个听起来就像是处理太多而且会增加计算复杂性。
我可以将equals
与重写{{1}}方法一起使用吗?我应该吗?
答案 0 :(得分:33)
正如杰夫福斯特所说:
Set.equals()方法仅用于比较两组的相等性。
您可以使用Set
删除重复的条目,但要注意:HashSet
不使用其包含对象的equals()
方法来确定相等。
HashSet
带有HashMap
个<Integer(HashCode), Object>
个条目,并使用equals()以及 HashCode 的equals方法来确定相等。< / p>
解决此问题的一种方法是覆盖您在Set中放入的类中的hashCode()
,以便它代表您的equals()
条件
例如:
class Fee {
String name;
public boolean equals(Object o) {
return (o instanceof Fee) && ((Fee)o.getName()).equals(this.getName());
}
public int hashCode() {
return name.hashCode();
}
}
答案 1 :(得分:8)
您可以而且应该使用Set来保存具有重写的equals方法的对象类型,但您也可能需要覆盖hashCode()。 Equal对象必须具有相同的哈希码。
例如:
public Fee{
public String fi;
public String fo;
public int hashCode(){
return fi.hashCode() ^ fo.hashCode();
}
public boolean equals(Object obj){
return fi.equals(obj.fi) && fo.equals(obj.fo);
}
}
(当然,必要时进行空检查。)
设置经常使用hashCode()来优化性能,如果你的hashCode方法被破坏,它将会出错。例如,HashSet uses an internal HashMap.
If you check the source code of HashMap,您将看到它依赖于元素的hashCode()和equals()方法来确定相等性:
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
如果未正确生成哈希,则可能永远不会调用您的equals方法。
为了让你的设置更快,你应该尽可能为不相等的对象生成不同的哈希码。
答案 2 :(得分:5)
Set
使用添加到集合中的对象的equals方法。 JavaDoc州
不包含重复元素的集合。更正式地说,集合不包含元素e1和e2对,例如e1.equals(e2),最多只有一个null元素。
Set.equals()
方法仅用于比较两个集合的相等性。它从未用作添加/删除集合中项目的一部分。
答案 3 :(得分:2)
一种解决方案是将TreeSet与比较器一起使用。
来自文档:
TreeSet实例使用compareTo(或compare)方法执行所有元素比较,因此从集合的角度来看,这个方法认为相等的两个元素是相等的。
这种方法比使用LinkedList快得多,但比HashSet慢一点(ln(n)vs n)。
值得注意的是,使用TreeSet的一个副作用是您的集合已经排序。
答案 4 :(得分:-1)