Java Set集合-override equals方法



有什么方法可以覆盖Set数据类型使用的equals方法吗?我为一个名为Fee的类编写了一个自定义的equals方法。现在我有一个FeeLnkedList,我想确保没有重复的条目。因此,我正在考虑使用Set而不是LinkedList,但决定两个费用是否相等的标准存在于Fee类中的overriden equals方法中。

如果使用LinkedList,我将不得不遍历每个列表项,并调用Fee类中的overriden equals方法,将其余项作为参数。单独阅读这篇文章听起来处理太多,会增加计算复杂性。

我可以将Set与重写的equals方法一起使用吗?我应该吗?

正如Jeff Foster所说:

Set.equals()方法仅用于比较两个集合的相等性。

您可以使用Set来消除重复的条目,但要注意:HashSet不使用其包含对象的equals()方法来确定相等性。

HashSet携带带有<Integer(HashCode), Object>条目的内部HashMap,并使用equals()以及HashCode的equals方法来确定相等性。

解决该问题的一种方法是覆盖您放入集合中的类中的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();
  }
}

您可以也应该使用Set来保存具有重写的equals方法的对象类型,但您可能也需要重写hashCode()相等的对象必须具有相等的哈希代码。

例如:

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使用内部HashMap。

如果你检查HashMap的源代码,你会发现它依赖于元素的hashCode()和equals()方法来确定相等性:

if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {

如果未正确生成哈希,则可能永远不会调用equals方法

为了加快设置速度,应尽可能为不相等的对象生成不同的哈希代码。

Set使用添加到集合中的对象的equals方法。JavaDoc声明

不包含重复元素的集合。更正式地说,集合不包含一对元素e1和e2,因此e1.equals(e2),最多包含一个null元素。

Set.equals()方法仅用于比较两个集合是否相等。它从未被用作从集合中添加/删除项目的一部分。

一种解决方案是使用带有比较器的TreeSet。

来自文件:

TreeSet实例使用其compareTo(或compare)方法执行所有元素比较,因此从集合的角度来看,该方法认为相等的两个元素是相等的。

这种方法比使用LinkedList快得多,但比HashSet慢一点(ln(n)vs n)。

值得注意的是,使用TreeSet的一个副作用是对集合进行排序。

Apache Commons Collection 中存在PredicatedList或PredicatedSet

最新更新