简单问题:下面Java程序的输出
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。
它们在哈希码方面相似但仍然不同吗?
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());
}
}
Why above program output is 3?
Edit
Seeing below comments I am extending my question:
System.out.println (s1 == s2);
Are s1 and s2 refering to same object? If then the above statement should print true but its output is false.
Are they are similar in terms of hashcode but still differnt?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
该集合中有两个不相等的
abc1
实例(请注意,它不会覆盖equals
或hashCode
)和一个字符串。让我们看一下四个add
调用:最初集合是空的 - 显然这会添加值。
这也会将值添加到集合中,因为它们是不同的对象,并且
equals
/hashCode
的默认实现基本上是引用标识。这会将值添加到集合中,因为字符串不等于任何一个当前值(不是字符串)。
这不会向集合中添加任何内容,因为第二个字符串等于第一个字符串。 (字符串覆盖
equals
/hashCode
。)结果是一个包含三个项目的集合。
There are two unequal instances of
abc1
(note that it doesn't overrideequals
orhashCode
) and one string in the set. Let's look at the fouradd
calls:Originally the set is empty - so obviously this will add the value.
This will also add the value to the set, because they are distinct objects and the default implementation of
equals
/hashCode
is basically reference identity.This will add the value to the set as the string isn't equal to either of the current values (which aren't strings).
This will not add anything to the set, as the second string is equal to the first. (String overrides
equals
/hashCode
.)The result is a set with three items in.
因为
set
结构(注意你的哈希图是如何由集合支持的)不允许存储两个相等的对象。这就是集合的行为方式。现在,您可能会误以为
a1
和a2
相等,但如果它们没有覆盖equals
或hashCode
那么对于 Java,它们不相等。但是,对于您的字符串s1
和s2
,它们确实是相等的,因为 String 实现已经覆盖了equals
和hashCode
方法。尝试执行s1.equals(s2)
,您将得到true
结果。如果您执行a1.equals(a2)
,您将得到false
。最后,您的哈希集包含 a1、a2 和 s1。
您扩展了您的问题,因此要回答...
s1
和s2
不引用同一个对象,它们是两个不同的 String 对象,但都表示同一组字符。由于它们不是同一个对象,System.out.println(s1 == s2)
打印false
。它们是equal()
,但不是同一个对象。Because the
set
structure (notice how your hashmap is backed by a set) does not allows two equal objects to be stored. That's how sets behave.Now, You may be fooled to think that both
a1
anda2
are equal, but if they don't overrideequals
orhashCode
then for Java they are not equal. However with your stringss1
ands2
, they are indeed equal because the String implementation already overrides theequals
andhashCode
methods. Try doings1.equals(s2)
and you'll get atrue
as result. If you doa1.equals(a2)
you'll getfalse
.At the end, your hashset contains a1, a2 and s1.
You extended your question, so to answer that...
s1
ands2
are not referring to the same object, they are two different String objects but both represent the same set of characters. Since they are not the same object,System.out.println(s1 == s2)
printsfalse
. They areequal()
, but not the same object.问题是这样的:
你可以尝试这样做:
然后你会看到
true
。 Set 不能包含相同的对象,这就是为什么只存储 s2 的原因。Here is the problem:
You can try to do:
and you see
true
. Set cannot contain same objects that's why only s2 is stored there.因为您要添加三个唯一的对象 - 两个 abc1 对象(您必须实现 equals 和 hashCode 方法来定义相等性)和一个 String(仅添加一个,因为它实现了这些方法,并且在String 对象相等)。
Because you're adding three unique objects -- the two abc1 objects (you would have to implement the equals and hashCode methods to define equality) and a String (only one is added because it HAS implemented these methods, and the data being compared in the String objects is equal).
HashSet 实现 Set 接口:
来自 http:// /java.sun.com/j2se/1.5.0/docs/api/java/util/Set.html:
不包含重复元素的集合。更正式地讲,集合不包含使 e1.equals(e2) 的一对元素 e1 和 e2,并且最多包含一个空元素。正如其名称所暗示的,该接口对数学集合抽象进行建模。
答:
我相信会发现 s1 和 s2 相等并且两者不能包含在 Set 中。无法确定 abc1 对象是否“相等”。因此,两者都被添加。
HashSet implements the Set interface:
From http://java.sun.com/j2se/1.5.0/docs/api/java/util/Set.html:
A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.
Answer:
I believe s1 and s2 will be found to be equal and both can not be contained within the Set. There is no way to determine that the abc1 objects are "equal". Thus, both get added.
Set 接口不允许重复元素。这就是您得到 3 作为输出的原因。
尽管上面创建了两个对象,但它们是相同的元素。
Set interface does not allow duplicate elements.Thats the reason you are getting 3 as output.
Even though above creates two objects but are identical elements.
给定
a1 != a2 ,因为您没有提供重写的 equals() ,如果它们包含的字符串相同,则该重写的 equals() 将声明 a1 和 a2 相同。
..并且..
HashSet
将仅保存唯一的对象。Given
a1 != a2 as you did not provide an overridden
equals()
that will state that a1 and a2 is same if the string they contain is same...And..
HashSet
will hold only unique objects.简短的回答:因为 HashSet 就像一个 数学集,仅根据定义拥有不同(独特)的对象。正如其他人在这里所说的,您放入的两个对象显然没有被评估为彼此不同。
The short answer: because a HashSet is like a mathematical set, which by definition only holds distinct (unique) objects. And as others have said here, two of the objects you put in are evidently not evaluated to be distinct from each other.