1

请帮助我确定像这样将 WrappedString 添加到 hashSet 之间的区别:

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");
 hs.add(ws1); hs.add(ws2);
 System.out.println(hs.size()); // outputs 2

   }

}

以及以下内容:

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>();
 String s1 = new String("aardvark");
 String s2 = new String("aardvark");
 hs.add(s1); hs.add(s2);
 System.out.println(hs.size()); // outputs 1
   }

}

我知道任何对象在 hashSet 中只存在一次,并且类型的两个实例WrappedString被认为是不同的变量,尽管它们具有相同的值,但是为什么它以不同的方式对待 String 类型的两个实例(尽管它们是两个不同的,但仅存储一个实例对象)?

4

3 回答 3

6

主要区别在于String实现equals,而您WrappedString没有。因此,从 HashSet 的角度来看,您可以添加任意数量new String("aardvark")的内容,它们都将被视为相同(因为new String("aardvark").equals(new String("aardvark"))是真的)并且只会添加一个。

而两个不同的WrappedString实例将不相等,即使它们包含的字符串相等(因为new WrappedString("aardvark").equals(new WrappedString("aardvark"))为假),所以集合不会将它们视为重复。

如果你想要一个类似于 的行为String,你需要在你的类中实现equals和。hashcodeWrappedString

于 2013-03-14T12:45:38.007 回答
0

WrappedString 类中的覆盖equalshashcode方法,那么它将按照您期望的方式运行。WrappedString 是不同的对象,即使这些对象包含相同的字符串对象。添加哈希码和等于,如下所示。

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");
        hs.add(ws1);
        hs.add(ws2);
        System.out.println(hs.size()); // outputs 2

    }
    @Override
    public boolean equals(Object obj) {
        WrappedString ws = (WrappedString)obj;
        return this.s.equals(ws.s);
    }
    @Override
    public int hashCode() {
        return this.s.hashCode();
    }

}

现在哈希集的大小将是 1。

于 2013-03-14T12:45:55.330 回答
0

考虑“等于”方法。对于字符串:new String("aardvark").equals(new String("aardvark"))将返回true,并且哈希集不会添加两个相等的实例。在您的包装器上,您没有实现 equals 方法,因此比较地址并且两个实例不相等 - 因此它们都插入到集合中。

于 2013-03-14T12:47:05.487 回答