【问题标题】:Remove element from HashSet从 HashSet 中移除元素
【发布时间】:2015-04-16 06:41:48
【问题描述】:

首先在 HashSet 中添加元素并打印 HashSet 的大小,返回结果如预期。但我修改了一个对象值并再次存储到 HashSet 并使用对象名称删除该对象。但我仍然得到与以前相同的大小。我的代码如下:

public class Test {

    private String s;
    public Test(String s){
        this.s  = s ;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        HashSet<Object> hs = new HashSet<Object>();
        Test t1 = new Test("Keval");
        Test t2 = new Test("Keval");

        String s1 = new String("Keval");        

        hs.add(t1);
        hs.add(t2);
        hs.add(s1);     
        System.out.println("Set Size :: " + hs.size());

        s1 = new String("Demo");        
        hs.remove(s1);
        System.out.println("Set Size :: " + hs.size());


    }
}

以上代码的输出是:

Set Size :: 3
Set Size :: 3    // Why it prints 3 insted of 2???

【问题讨论】:

  • 提示:"Keval"!="Demo"
  • 并不是说它回答了你的问题,但是如果你想在像 HashSet 这样的哈希结构中使用它们,你应该在你的 Test 类中实现 hashcodeequals 方法。
  • s1 值在hs.remove(s1); 语句之前已更改
  • 您正在尝试删除 hashSet 中不存在的对象,以标识您必须覆盖 .equals 和 .hashcode。
  • @Rupesh 你想说的是,如果我修改了 hashset 对象的值,然后我从 HashSet 中删除了该对象,它不会删除该对象,它仍然指向该对象?跨度>

标签: java string hashset


【解决方案1】:
String s1 = new String("Keval");     
....
hs.add(s1); 
....
s1 = new String("Demo");        
hs.remove(s1);

您正在向您的HashSet 添加一个等于String“Keval”的String,但您正试图从@987654327 中删除一个等于String“演示”的String @。

您的HashSet 不包含等于“Demo”的String,因此remove() 调用不会从Set 中删除任何内容,并且不会影响其大小。

当您删除s1 = new String("Demo") 行时,s1 仍然指的是添加到Set(等于“Keval”)的String,因此hs.remove(s1) 删除了@987654337 @来自Set

【讨论】:

  • 你能详细说明你的答案吗?因为当我删除 s1 = new String("Demo");从代码来看它工作正常。
  • @KevalTrivedi 您已添加到您的集合new String("Keval");,但正在尝试删除不相等的对象new String("Demo");。换句话说,您正在尝试删除集合中不存在的对象。
  • @Eran 是的,我明白你的意思。它使用equals方法检查值并返回false。这就是为什么它没有删除元素。我说的对吗?
  • @KevalTrivedi 它可能甚至无法运行equals 方法,因为hashCode 很可能不同,所以这两个字符串可能映射到不同的桶。
【解决方案2】:

如果您希望 Hashset 识别您的对象,则必须重写 equals 和 hashcode 方法。

由于您添加了“Keval”并尝试删除“Demo”,因此无需设置任何更改。

请记住,由于您使用的是对象的 HashSet,因此在使用可能会产生意想不到的后果的 hashcode 和 equals 方法时要小心。 See this question 了解更多详情。

【讨论】:

    【解决方案3】:

    您的问题有多个问题,我认为您应该学习一些基础知识。

    1. 每当您执行新操作时,都会创建一个新对象。 s1 = new String("Demo");

    2. Hashset 适用于对象的hashcode()equals()。因此,如果您使用自己的类添加到 Hashset,请覆盖这两个方法。如需了解更多信息,请在 Google 上搜索。

    3. 现在解决您的问题,当您通过以下方式创建新对象时 s1 = new String("Demo"); 然后尝试通过hs.remove(s1); 从hashset 中删除那个new 对象,hashset 将使用方法equals()hashcode() 来识别应该删除的对象。由于这个新对象不存在于哈希集中,因此不会删除任何内容。

    因此尺寸不变。

    【讨论】:

      【解决方案4】:

      在您执行s1 = new String("Demo") 之后,引用s1 只是指新对象,而不是HashSet 上的那个。

      所以它不会从集合中删除任何东西

      【讨论】:

        【解决方案5】:

        HashSet 通过计算 key 的 hashcode 来找到 hashset 中的 bucket/location。 在 hs 中添加 s1 时,您的密钥是“Keval”,它将生成一个哈希码,并且 s1 对象将存储在该存储桶中。 现在您已将 s1 更改为“Demo”。删除 s1 时,将根据键“Demo”生成的哈希码搜索存储桶。此存储桶在 hs 中未找到,因此未删除。 “Keval”和“Demo”的哈希码不一样。 希望这能消除您的困惑并回答您的疑问。

        【讨论】:

          【解决方案6】:

          您正在将字符串初始化为 new String,这将在字符串池中创建新字符串。如果您在更改字符串值之前删除,它将从哈希集中删除,并且大小为 2(其因为当您添加hs.remove 时,s1 的值是“Demo”而不是“keval”。

              String s1 = new String("Keval");  
              hs.add(t1);
              hs.add(t2);
              hs.add(s1);     
              System.out.println("Set Size :: " + hs.size());  //3
              s1 = new String("Demo"); 
              hs.remove(s1);   //equals() method fails to find Demo and none of the element will be removed
              System.out.println("Set Size :: " + hs.size());
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-06-30
            • 1970-01-01
            • 2015-11-16
            • 2010-11-09
            • 1970-01-01
            • 2023-03-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多