简体   繁体   中英

How to Remove an element from HashSet?

I want to remove an element from a HashSet. Can sb help me to understand, why cat "emma" cant be removed from this HashSet? What could be the best solution?

Thank you!

public static void main(String[] args) {

    HashSet<Cat> set = new HashSet<Cat>();
    
    set.add(new Cat("cindy"));
    set.add(new Cat("emma"));
    
    Iterator<Cat> iterator = set.iterator();

    while (iterator.hasNext()) {
        Cat name1 = iterator.next();

        if (name1.equals("emma")) {
            iterator.remove();
        }
    }
    System.out.println(set);
}

public static class Cat {
    private String name;

    public Cat(String name) {
        this.name = name;
    }

    public String toString() {
        return this.name;
    }
}

You are using the equals method of a Cat with a string as an argument, which returns false. You can use the toString method as you have overridden it, or have a getter for the name and compare it with the string.

boolean equals(Object anObject)

Pay attention, that equals method accepts Objects , so you do not get an exception when two variables are not String as you expect (by the way, IntelliJ IDEA gives you an inspection for this case). All you need to fix it is to compare String "emma" with name1.name :

while (it.hasNext()) {
    Cat name1 = it.next();

    if ("emma".equals(name1.toString()))
        it.remove();
}

You can see your problem running the following code:

Cat c = new Cat("emma");
if(c.equals("emma"))
    System.out.println("true"); // this is what you expect
else
    System.out.println("false!"); // this is what actually happens!

This is because if the equals method is not defined, by default it compares that the two objects are exactly the same. You can find more information about this behavior here and here . In your case you are comparing a String object with a Cat object.

One possible solution would be to use the toString method you hava defined in your class to compare between strings. The equals method is overridden in the String class to have the behavior you expect.

public static void main(String[] args) {

    HashSet<Cat> set = new HashSet<Cat>();
    
    set.add(new Cat("cindy"));
    set.add(new Cat("emma"));
    
    Iterator<Cat> iterator = set.iterator();

    while (iterator.hasNext()) {
        Cat name1 = iterator.next();

        if (name1.toString().equals("emma")) {
            iterator.remove();
        }
    }
    System.out.println(set);
}

Another solution could be to override the equals method in your cat class. Here is a way you could do it:

import java.util.*;

class Cat {
    private String name;

    public Cat(String name) {
        this.name = name;
    }

    public String toString() {
        return this.name;
    }

    public Boolean equals(Cat other) {
        return this.name.equals(other.name);
    }
}
public class Test {
public static void main(String[] args) {
    HashSet<Cat> set = new HashSet<Cat>();
    
    Cat cindy = new Cat("cindy");
    Cat emma = new Cat("emma");

    set.add(cindy);
    set.add(emma);
    
    Iterator<Cat> iterator = set.iterator();

    while (iterator.hasNext()) {
        Cat cat = iterator.next();

        if (cat.equals(emma)) {
            iterator.remove();
        }
    }
    System.out.println(set);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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