HashSet允许重复
我似乎无法让HashSet
实例按预期工作。 我使用的代码如下:
import testing.Subclass; import java.util.HashSet; public class tester { public static void main(String[] args) throws Exception { HashSet set = new HashSet(); set.add(new Subclass("007812")); set.add(new Subclass("007813")); System.out.println("Set size " + set.size()); set.add(new Subclass("007812")); System.out.println("Set size " + set.size()); for(Subclass sub : set) { System.out.println(" sub acctNbr " + sub.getAcctNbr()); } } }
子类
public class Subclass implements Comparable { public Subclass(String acctNbr) { this.acctNbr = acctNbr; } private String acctNbr; public String getAcctNbr() { return this.acctNbr; } public int compareTo(Subclass other) { return this.getAcctNbr().compareTo(other.getAcctNbr()); } public boolean equals(Subclass other) { if(other.getAcctNbr().equals(this.getAcctNbr())) return true; else return false; } public int hashCode() { return acctNbr.hashCode(); } }
此代码输出
sross@sross-workstation:~/Documents$ javac testing/Subclass.java sross@sross-workstation:~/Documents$ javac tester.java sross@sross-workstation:~/Documents$ java tester Set size 2 Set size 3 sub acctNbr 007812 sub acctNbr 007812 sub acctNbr 007813 sross@sross-workstation:~/Documents$
您需要覆盖equals(Object)
。 你没有这样做,而是实现了一个带有签名equals(Subclass)
的equals
方法。 因此,您的HashSet
使用equals(Object)
定义的默认equals(Object)
方法进行相等性测试。
默认的equals(Object)
实现基于对象标识,因此set“允许”添加两个String
,虽然在语义上相同,但它们不是同一个对象。
您没有正确覆盖Object.equals()
。
@Override public boolean equals(Object other) { if ((other == null) || !(other instanceof Subclass)) { return false; } return ((Sublcass) other).getAcctNbr().equals(this.getAcctNbr()); }
boolean equals(Subclass other)
方法创建了第二个方法,而不是您打算做的。
两个要点:
首先,每当您认为自己重写方法时,养成使用@Override
的习惯。 这会导致您的示例代码无法编译,导致您发现问题。
其次,如果您正在使用IDE,并且它没有为您突出显示一个很好的大胆警告,则它配置错误! 你应该解决它!
如果你没有使用IDE – 你真的,真的应该。 一旦键入public boolean equals(Subclass other)
,文本就会改变颜色,并会显示一条警告,告诉您可能出现的问题。
顺便说一下,我收集的equals()
的标准习惯是:
@Override public boolean equals(Object object) { if (object instanceof Subclass) { Subclass that = (Subclass) object; return this.anInt == that.anInt && this.aString.equals(that.aString); // for example } return false; }
在某些情况下,值得添加一个if (object == this) { return true; }
但是,养成它的习惯是不值得的。
我有几乎相同的问题,因为每个人都说你需要覆盖正确的public boolean equals(Object o)
方法。 但这还不够!
还必须覆盖public int hashCode()
(就像你一样),否则,java根本不会调用equals
方法。
首先猜测,看起来你的equals(Subclass other)
应该是equals(Object other)
,以便根据需要覆盖java.lang.Object.equals()
方法。 该集合可能正在调用底层的equals()
实现。
永远不会调用你的equals方法。 equals
的签名要求它接受一个Object
,而不是其他一些类(包括碰巧实现equals
任何类)。
public boolean equals(Object other) { ... }