4
public class abc1 {

 private String s;

 public abc1(String s){this.s=s;}
 public static void main(String args[])
 {
  HashSet<Object> hs=new HashSet<Object>();
  abc1 a1= new abc1("abc");
  abc1 a2= new abc1("abc");
  String s1= new String("abc");
  String s2= new String("abc");
  hs.add(a1);
  hs.add(a2);
  hs.add(s1);
  hs.add(s2);
  System.out.println(hs.size());

 }
}

为什么上面的程序输出是3?

编辑

看到以下评论,我正在扩展我的问题:

System.out.println (s1 == s2);

s1 和 s2 是指同一个对象吗?如果那么上面的语句应该打印 true 但它的输出是 false。

它们在哈希码方面是否相似但仍然不同?

4

8 回答 8

10

集合中有两个不相等的实例abc1(注意它不会覆盖equalshashCode)和一个字符串。让我们看一下这四个add调用:

hs.add(a1);

最初该集合是空的 - 所以显然这会增加价值。

hs.add(a2);

这也会将值添加到集合中,因为它们是不同的对象并且equals/的默认实现hashCode基本上是引用标识。

hs.add(s1);

这会将值添加到集合中,因为字符串不等于任何一个当前值(不是字符串)。

hs.add(s2);

不会向集合中添加任何内容,因为第二个字符串等于第一个字符串。(字符串覆盖equals/ hashCode。)

结果是一个包含三个项目的集合。

于 2010-04-28T17:09:51.793 回答
2

因为set结构(注意你的哈希图是如何由一组支持的)不允许存储两个相等的对象。这就是集合的行为方式。

现在,您可能会误以为两者a1a2是相等的,但是如果它们不覆盖equals,或者hashCode对于 Java,它们就不相等。但是,对于您的字符串s1and s2,它们确实是相等的,因为 String 实现已经覆盖了equalsandhashCode方法。尝试做s1.equals(s2),你会得到一个true结果。如果你这样做a1.equals(a2),你会得到false.

最后,您的哈希集包含 a1、a2 和 s1。

你扩展了你的问题,所以回答这个...

s1并且s2不是指同一个对象,它们是两个不同的 String 对象,但都表示同一组字符由于它们不是同一个对象,因此System.out.println(s1 == s2)打印false. 它们是equal(),但不是同一个对象。

于 2010-04-28T17:21:29.443 回答
1

这是问题所在:

String s1= new String("abc");
String s2= new String("abc");

你可以尝试这样做:

System.out.println (s1 == s2);

你看true。Set 不能包含相同的对象,这就是为什么只有 s2 存储在那里。

于 2010-04-28T17:13:01.903 回答
0

因为您要添加三个唯一的对象——两个 abc1 对象(您必须实现 equals 和 hashCode 方法来定义相等性)和一个 String(只添加一个,因为它已经实现了这些方法,并且正在比较的数据在String 对象是相等的)。

于 2010-04-28T17:11:33.843 回答
0

HashSet 实现了 Set 接口:

public interface Set<E> extends Collection<E>

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Set.html

不包含重复元素的集合。更正式地说,集合不包含一对元素 e1 和 e2 使得 e1.equals(e2),并且最多包含一个空元素。正如它的名字所暗示的,这个接口模拟了数学集合抽象。

回答:

我相信 s1 和 s2 会被发现是相等的,并且两者都不能包含在 Set 中。无法确定 abc1 对象是否“相等”。因此,两者都被添加。

于 2010-04-28T17:14:05.683 回答
0

简短的回答:因为 HashSet 就像一个数学集合,根据定义,它只包含不同的(唯一的)对象。正如其他人在这里所说的那样,您放入的两个对象显然没有被评估为彼此不同。

于 2010-04-28T17:17:52.260 回答
0

设置接口不允许重复元素。这就是你得到 3 作为输出的原因。

String s1= new String("abc");
  String s2= new String("abc");

即使上面创建了两个对象,但它们是相同的元素。

于 2010-04-28T17:20:12.560 回答
0

给定

  abc1 a1= new abc1("abc");
  abc1 a2= new abc1("abc");

a1 != a2 因为您没有提供一个覆盖equals(),如果它们包含的字符串相同,则表明 a1 和 a2 是相同的。

..和..

HashSet将只保存唯一的对象。

于 2010-04-28T17:21:54.840 回答