Java Set集合 - 覆盖equals方法

Fai*_*yet 20 java overriding equals set

有没有办法覆盖数据类型equals使用的方法Set?我equals为一个叫做的类写了一个自定义方法Fee.现在我有一个LnkedList,Fee我想确保没有重复的条目.因此,我正在考虑使用a的Setinsted LinkedList,但是决定两个费用是否相等的标准存在于类中的overriden equals方法中Fee.

如果使用a LinkedList,我将遍历每个列表项并equalsFee类中调用overriden 方法,其余条目作为参数.仅仅阅读这个听起来像是太多的处理并且会增加计算复杂性.

我可以使用Set重写equals方法吗?我是不是该?

Jon*_*her 34

正如杰夫福斯特所说:

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

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

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

解决该问题的一种方法是覆盖hashCode()您放入Set中的Class,以便它代表您的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();
  }

}
Run Code Online (Sandbox Code Playgroud)

  • `HashSet`遵循`Set`契约,它需要使用`equals()`方法来确定相等性.但它利用了这样一个事实,即如果`equ`()是另一个对象,则`Object`需要具有相同的`hashCode()`.你可以**在一个`HashSet`中有多个具有相同`hashCode()`值的对象. (7认同)

Sha*_*ley 8

您可以而且应该使用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);
    }
}
Run Code Online (Sandbox Code Playgroud)

(当然,必要时进行空检查.)

集通常使用hashCode()来优化性能,如果你的hashCode方法被破坏,它会出错.例如,HashSet使用内部HashMap.

如果检查HashMap的源代码,您将看到它依赖于元素的hashCode()和equals()方法来确定相等性:

if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
Run Code Online (Sandbox Code Playgroud)

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

为了使您的设置更快,您应该尽可能为不相等的对象生成不同的哈希码.

  • 我知道这是一个例子,但你不应该使用连接来生成hashCode.就像你说的那样,hashCode方法可能经常被调用,字符串连接是一个缓慢而昂贵的操作.更好的方法是简单地对字符串hashCode进行异或.例如:`return fi.hashCode()^ fo.hashCode();`此外,你的`equals()`方法有点过度杀戮.你不必将`fi`与`fo`进行比较,然后将`fo`与`fi`进行比较.`Object` Javadoc清楚地表明`equals()`方法必须是对称的.因此,只有performin`fit.equals(fo)`就足够了(忽略`null`). (3认同)

Jef*_*ter 5

Set使用添加到集合中的对象的equals方法.该JavaDoc的状态

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

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