简单问题:输出以下Java程序

Abh*_*ain 4 java equality hashset

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());

 }
}
Run Code Online (Sandbox Code Playgroud)

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

编辑

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

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

s1和s2是否指向同一个对象?如果那么上面的语句应该打印为true但其输出为false.

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

Jon*_*eet 10

有两个不等的实例abc1(注意它不会覆盖equalshashCode)和集合中的一个字符串.我们来看四个add电话:

hs.add(a1);
Run Code Online (Sandbox Code Playgroud)

最初的设置是空的 - 显然这会增加价值.

hs.add(a2);
Run Code Online (Sandbox Code Playgroud)

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

hs.add(s1);
Run Code Online (Sandbox Code Playgroud)

这将向集合添加值,因为字符串不等于任何当前值(不是字符串).

hs.add(s2);
Run Code Online (Sandbox Code Playgroud)

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

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