Java 哈希集大小问题

Java 哈希集大小问题,java,hashset,Java,Hashset,在下面的示例中,我创建了hashset,在其中添加了三个字符串值 s1、s2、s3,尽管它显示了哈希集1的大小。为什么? public static void main(String args[]) { String s1="abc"; String s2=new String("abc"); String s3="abc"; Set setdemo=new HashSet(); setdemo.add(s1); setdemo.add(s2);

在下面的示例中,我创建了hashset,在其中添加了三个字符串值 s1、s2、s3,尽管它显示了哈希集1的大小。为什么?

public static void main(String args[])
{
    String s1="abc";
    String s2=new String("abc");
    String s3="abc";
    Set setdemo=new HashSet();
    setdemo.add(s1);
    setdemo.add(s2);
    setdemo.add(s3);

    System.out.println("s1 hashcode -:"+ System.identityHashCode(s1));
    System.out.println("s2 hashcode -:"+ System.identityHashCode(s2));
    System.out.println("s3 hashcode -:"+ System.identityHashCode(s3));
    System.out.println("Set size is -:"+setdemo.size());
}
输出:

s1 hashcode -:17523401
s2 hashcode -:8567361
s3 hashcode -:17523401
Set size is -:1

集合不允许重复。当字符串放入池中时,它们都指向同一个实例。

因为在HashSet中只保存唯一的条目。此处“abc”被添加了3次,因此即使您添加了多次,也只会保存字符串abc

重复
被标识为具有等效哈希代码,并且在测试相等性时返回


在您的情况下,所有3个
字符串
都被标识为重复项,并且由于
Set
消除了重复项,因此在您的情况下大小为
1

哈希集不存储相等对象的倍数-它是一个“集”。您应该使用一个MultiSet(也称为Bag)实现,例如来自Apache Commons Collections或Guava的实现,这些实现还存储您添加的拷贝数。

如果集合中不包含任何元素,则将指定元素
e
添加到此集合中 元素
e2
使得
(e==null?e2==null:e.equals(e2))

因此,在上述添加操作期间:

s2.equals(s1)
返回
true
s2
不会被添加


s3.equals(s1)
返回
true
s3
也不会被添加到
setdemo
中。

每个字符串都将由hash()函数返回类似的hashCode。并且Set不允许重复,它肯定会覆盖该位置上的上一个值。

检查输出是否存在重复

s1.equals(s2)
s2.equals(s3)

它的
String
class equals方法不允许您一次又一次地添加相同的对象,因为HashSet使用equals方法来标识对象是否相同。

每当我们创建String类的对象时,它都会检查值是否已经存储在其他字符串中。 像

在这种情况下,它不会为s1和s2分配两个内存位置,而是只分配一个。当我们使用.equals()操作数进行检查时,它会检查内存位置是否相同。 在:


我们正在创建三个内存位置(简单来说),但当HashSet内部检查(同样是简单来说)是否为.equals时,它会告诉它相同的内存位置,因此HashSet的大小为1。

字符串相等性通过重写的equals()方法进行测试。该方法考虑字符串的内容。这就是为什么s1!=s2,s2不在集合中。s1.equals(s2)返回true。它们不都指向同一个实例,因为字符串s2没有放入字符串池。@ghdalum是对的,sudhanshu它们不指向同一个实例。s2是一个新的实例,即使hascode o/p也说了相同的.Set接口,用于保存不同的对象。s1.等于(s2)是真的。因此哈希集的大小将保持为2
String s1 = "hello";
String s2 = "hello";
setdemo.add(s1);
setdemo.add(s1);
setdemo.add(s1);