2015-06-22 31 views
1

这里是其产生的HashSet大小3代替2为什么对象不相同添加有相同的值,HashSet的,甚至的hashCode和equals被覆写

package dump.test; 
import java.util.*; 
public class WrappedString { 
    private String s; 
    public WrappedString(String s) { this.s = s; } 
    public static void main(String[] args) { 
     HashSet<Object> hs = new HashSet<Object>(); 
     WrappedString ws1 = new WrappedString("aardvark"); 
     WrappedString ws2 = new WrappedString("aardvark"); 
     String s1 = new String("aardvark"); 
     String s2 = new String("aardvark"); 
     hs.add(ws1); hs.add(ws2); hs.add(s1); hs.add(s2); 
     System.out.println(hs.size()+hs.toString()); 
    } 
    public boolean equals(Object aSong) { 
     String s = aSong.toString(); 
     System.out.println(s); 
     return s.equals(this.s); 
    } 
    public int hashCode() { 
     System.out.println(this.s + "-" + this.s.hashCode()); 
     return this.s.hashCode(); 
    } 
    /*public int compareTo(Object aSong) { 
     String s = aSong.toString(); 
     return this.s.compareTo(s); 
    }*/ 
} 
代码

它总是打印下面输出如果equals和hashCode被覆盖 enter image description here

你可以看到具有输出相同的代码,但算作不同,产生的数为3

两个对象,这是如果不重写equals和hashCode enter image description here

请协助我如何工作。

+0

你的平等方法甚至不会为'ws1.equals(ws2)' –

回答

3

问题是你的情况是不对称的。如果实现决定调用String实例上的equals,并将您的类作为参数,那么它肯定会返回false,因此您的代码将不会始终工作。

+0

返回true谢谢塞巴斯蒂安!以上代码中的两个WrappedString对象可以做出哪些努力是相同的。我想在上面的代码中计算为2。 –

+0

添加公共字符串toString(){return this.s; }清除了我的困惑。 –

2

Javadoc中的Set接口:

不包含重复元素的集合。更正式地,集合不包含e1和e2这样的元素对,使得e1.equals(e2)和至多一个空元素。正如其名称所暗示的那样,该界面模拟数学集抽象。

因此,HashSet在添加新元素之前检查equals(Object)。由于第二个字符串等于第一个字符串,因此不会添加。在你的WrappedString上,你不是覆盖equals(Object),所以,你使用的是从Object继承的,它只是检查对象ID(在你的情况下为659e0bfd2a139a55)。

+0

谢谢jpkrohling!如果遇到对象ID 2fcf3776(按照第一张图片),怎么办?所以我认为这两个ID是相同的,等于会发现值太相同,它将被添加为一个集合,但它不是。以上代码中的两个WrappedString对象可以做出哪些努力是相同的。我想在上面的代码中计算为2。 –

+0

事实上,我的答案并非100%正确,因为对象比较了对象的内部ID。为了你的代码的工作,我会说你需要让你的WrappedString#equals来比较内部字符串,并让你的toString返回底层字符串。 – jpkrohling

+0

荣誉jpkrohling!它就像你说的那样工作。我需要重写一个工厂方法,toString并使其返回底层字符串值。以前,它无法从对象转换为字符串,并且可能会导致不同的对象,尽管具有相同的对象ID。下面的小片段作品: public String toString(){ \t \t return this。S; \t} –

0

加入

public String toString() { return this.s; }

清除我的困惑。以前,它无法将铸造对象的真实值转换为字符串,并且需要覆盖toString以返回基础值。

相关问题