简体   繁体   English

从HashSet中删除元素

[英]Remove element from HashSet

First of all add the element in HashSet and prints the size of HashSet which returns as expected. 首先在HashSet中添加元素并打印HashSet的大小,该大小按预期返回。 but i modified one of the object value and again store in to HashSet and remove the object using object name. 但我修改了一个对象值并再次存储到HashSet并使用对象名称删除对象。 but still i get the same size as previous. 但我仍然和以前一样大小。 My code is as under : 我的代码如下:

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


    }
}

Output of above code is : 上述代码的输出是:

Set Size :: 3
Set Size :: 3    // Why it prints 3 insted of 2???
String s1 = new String("Keval");     
....
hs.add(s1); 
....
s1 = new String("Demo");        
hs.remove(s1);

You are adding a String which is equal to the String "Keval" to your HashSet , but you are trying to remove a String equal to the String "Demo" from the Set . 要添加String等于该String “Keval”你HashSet ,但是你想删除一个String等于String从“演示” Set

Your HashSet contains no String equal to "Demo", so the remove() call removes nothing from the Set , and doesn't affect its size. 您的HashSet包含等于“Demo”的String ,因此remove()调用不会从Set删除任何内容,也不会影响其大小。

When you remove the s1 = new String("Demo") line, s1 still refers to the String that was added to the Set (the one which is equal to "Keval"), so hs.remove(s1) removes that String from the Set . 删除s1 = new String("Demo")行时, s1仍然引用添加到SetString (等于“ hs.remove(s1) ”的String ),因此hs.remove(s1)从中删除该String Set

If you want the Hashset to identify your object, you will have to override the equals and hashcode method. 如果希望Hashset标识对象,则必须覆盖equals和hashcode方法。

Since you added "Keval" and tried to remove "Demo" there are no changes to set. 由于您添加了“Keval”并尝试删除“Demo”,因此无需更改设置。

Remember since you are using HashSet of Objects, be careful while playing with hashcode and equals method that may have unintended consequences. 请记住,因为您正在使用HashSet of Objects,所以在使用hashcode和equals方法时要小心,这可能会产生意想不到的后果。 See this question for more detail about this. 有关详细信息, 请参阅此问题

Your problem have multiple issues, and I think you should learn a few basics. 你的问题有很多问题,我认为你应该学习一些基础知识。

  1. Whenever you do a new, it creates a new object. 每当您执行新操作时,它都会创建一个新对象。 s1 = new String("Demo");

  2. Hashset works on object's hashcode() and equals() . Hashset适用于对象的hashcode()equals() So if you are using your own class to be added to Hashset, please override both of these methods. 因此,如果您使用自己的类添加到Hashset,请覆盖这两种方法。 For more learning, please google them. 如需更多学习,请谷歌搜索。

  3. Now for your problem, when you created a new object by doing s1 = new String("Demo"); 现在针对您的问题,当您通过执行s1 = new String("Demo");创建新对象时s1 = new String("Demo"); and then trying to remove that new object from hashset by hs.remove(s1); 然后尝试通过hs.remove(s1);从hashset中删除该对象hs.remove(s1); , hashset will use methods equals() and hashcode() to identify the object that should be removed. ,hashset将使用equals()hashcode()来标识应该删除的对象。 Since this new object is not present in the hashset, nothing will be removed. 由于这个新对象不存在于hashset中,因此不会删除任何内容。

Hence the size is un-changed. 因此,大小是不变的。

After you do s1 = new String("Demo") , reference s1 is simply referring to the new object and not the one on HashSet. 在执行s1 = new String("Demo") ,引用s1只是引用新对象而不是HashSet上的对象。

So it is not removing anything from set 所以它不会从集合中移除任何东西

You are initializing the string as new String which will create new one in the string pool.If you remove before changing the string value it will remove from hash set and will give size as two(Its because when you added hs.remove ,s1 value is "Demo" not "keval". 您正在将字符串初始化为新字符串 ,它将在字符串池中创建新字符串。如果在更改字符串值之前删除它将从哈希集中删除并将大小设置为2(因为当您添加hs.remove ,s1值是“演示”不是“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());

HashSet finds bucket/location in hashset by calculating hashcode of key. HashSet通过计算密钥的哈希码来查找哈希集中的桶/位置。 While adding s1 in hs your key was "Keval" which will generate a hashcode and s1 object will be stored in that bucket. 在hs中添加s1时,你的密钥是“Keval”,它将生成一个哈希码,s1对象将存储在该桶中。 Now you have changed s1 to "Demo". 现在您已将s1更改为“Demo”。 While removing s1, bucket will be searched based on hashcode generated from key "Demo". 在删除s1时,将根据密钥“Demo”生成的哈希码搜索bucket。 This bucket is not found in hs and hence its not deleted. 在hs中找不到此存储桶,因此不会将其删除。 Hashcode of "Keval" and "Demo" is not same. “Keval”和“Demo”的哈希码不相同。 Hope this clears your confusion and answers your query. 希望这可以解决您的困惑并回答您的疑问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM