简单问题:下面的Java程序的输出 公共类abc1{ 私有字符串; 公共abc1(字符串s){this.s=s;} 公共静态void main(字符串参数[]) { HashSet hs=新的HashSet(); abc1 a1=新的abc1(“abc”); abc1 a2=新的abc1(“abc”); 字符串s1=新字符串(“abc”); 字符串s2=新字符串(“abc”); hs.添加(a1); hs.加入(a2); hs.加入(s1); 加上(s2); System.out.println(hs.size()); } }
为什么上面的程序输出是3 编辑 看到下面的评论,我扩展了我的问题: System.out.println(s1==s2) s1和s2是指同一个对象吗?如果是,则上述语句应打印为true,但其输出为false简单问题:下面的Java程序的输出 公共类abc1{ 私有字符串; 公共abc1(字符串s){this.s=s;} 公共静态void main(字符串参数[]) { HashSet hs=新的HashSet(); abc1 a1=新的abc1(“abc”); abc1 a2=新的abc1(“abc”); 字符串s1=新字符串(“abc”); 字符串s2=新字符串(“abc”); hs.添加(a1); hs.加入(a2); hs.加入(s1); 加上(s2); System.out.println(hs.size()); } },java,equality,hashset,Java,Equality,Hashset,为什么上面的程序输出是3 编辑 看到下面的评论,我扩展了我的问题: System.out.println(s1==s2) s1和s2是指同一个对象吗?如果是,则上述语句应打印为true,但其输出为false 它们在hashcode方面是否相似但仍然不同?有两个不同的abc1(请注意,它不会覆盖equals或hashcode)实例和集合中的一个字符串。让我们看看四个add调用: public class abc1 { private String s; public abc1(String
它们在hashcode方面是否相似但仍然不同?有两个不同的
abc1
(请注意,它不会覆盖equals
或hashcode
)实例和集合中的一个字符串。让我们看看四个add
调用:
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());
}
}
最初,集合是空的-因此很明显,这将增加值
hs.add(a1);
这也会将值添加到集合中,因为它们是不同的对象,equals
/hashCode
的默认实现基本上是引用标识
hs.add(a2);
这将向集合中添加值,因为字符串不等于当前值(不是字符串)
这不会向集合中添加任何内容,因为第二个字符串等于第一个字符串。(字符串重写等于
/hashCode
)
结果是一个集合,其中包含三个项。,因为您要添加三个唯一的对象——两个abc1对象(必须实现equals和hashCode方法来定义相等)和一个字符串(仅添加一个,因为它实现了这些方法,并且字符串对象中比较的数据相等).问题是:
hs.add(s2);
您可以尝试执行以下操作:
String s1= new String("abc");
String s2= new String("abc");
您会看到
true
。集合不能包含相同的对象,这就是为什么只有s2存储在那里。HashSet实现集合接口:
System.out.println (s1 == s2);
公共接口集扩展集合
发件人:
不包含重复元素的集合。更正式地说,集合不包含e1和e2元素对,因此e1.equals(e2)最多包含一个空元素。正如它的名字所暗示的,这个接口为数学集合抽象建模
答复:
我相信s1和s2是相等的,两者不能包含在集合中。无法确定abc1对象是否“相等”。因此,两者都被添加了。简短的回答是:因为哈希集就像一个,根据定义,它只保存不同的(唯一的)对象。正如其他人在这里所说的,您输入的两个对象显然没有被评估为彼此不同。Set接口不允许重复元素。这就是您将3作为输出的原因
public interface Set<E> extends Collection<E>
尽管上面创建了两个对象,但它们是相同的元素。因为
集合
结构(注意你的hashmap是如何被集合支持的)不允许存储两个相等的对象。这就是布景的表现
现在,您可能会被愚弄到认为a1
和a2
都是相等的,但是如果它们不覆盖equals
或hashCode
,那么对于Java,它们就不相等。但是,对于字符串s1
和s2
,它们实际上是相等的,因为字符串实现已经覆盖了equals
和hashCode
方法。尝试执行s1.equals(s2)
,结果将是true
。如果你做了a1.equals(a2)
你会得到false
最后,哈希集包含a1、a2和s1
你扩展了你的问题,所以要回答
s1
和s2
是不指同一个对象,它们是两个不同的字符串对象,但都代表同一组字符。由于它们不是同一个对象,System.out.println(s1==s2)
打印false
。它们是相等的,但不是同一个对象。给定
String s1= new String("abc");
String s2= new String("abc");
a1!=a2,因为您没有提供重写的equals()
,如果a1和a2所包含的字符串相同,则该重写的equals()将声明a1和a2相同
…和
HashSet
将只保存唯一的对象。使用“code”按钮格式化代码,这在眼睛里更容易。@leonbloy谢谢。..nxt时间我会的。即使在正确的设置之后仍然存在问题-只存储a1、a2和s1。此外,您的输出代码仍将输出false,因为==检查引用相等,而不是对象相等。@Jon Skeet:这也是一个打字错误)我只是复制了错误的代码块,然后使用了它的变量名。System.out.println(s1==s2)代码>将打印false
。哈希集认为s1
和s2
相同的原因是在String
上实现了hashCode
s1
和s2
不是同一个对象,但是它们重写的equals&hashcode方法意味着相等。@Bill:我相信s1!=s2,所以它们不是同一个实例。之所以只添加一个,是因为HashSet使用equals,字符串覆盖equals,而abc不覆盖。
String s1= new String("abc");
String s2= new String("abc");
abc1 a1= new abc1("abc");
abc1 a2= new abc1("abc");