1

I have 2 Hash Sets, both containing x amount of "Names" (Object). What I would like to do is find out if my "Names" in Names1 or in Names2 ?

 public static void main (String[] args) {

 Set<Name> Names1 = new HashSet<Name>();
    Names1.add(new Name("Jon"));
    Names1.add(new Name("Mark"));
    Names1.add(new Name("Mike"));
    Names1.add(new Name("Helen"));
    Set<Name> Names2 = new HashSet<Name>();
    Names2.add(new Name("Mark"));
    Names2.add(new Name("Mike"));
    Names2.add(new Name("Sally"));



    Set<Name> listCommon = new HashSet<Name>(); 

    for (Name element : Names1) {
        if (!Names2.contains(element)) {
            listCommon.add(element);
        }
    }

    for (Name element : listCommon) {
        System.out.println(element.getNameString());
    }

}
public class Name {
String ord;

Name(String ord1){
    ord = ord1;
}

public String getNameString(){
    return ord;
}
}

So when I ran this code, I got no output at all, cause the

'if (!Names2.contains(element)) {' 

never occurred. But what I would like to get as output would be Jon and Helen. Since they are not in Names2.

Seeker
  • 303
  • 7
  • 17
Noksuu
  • 11
  • 1

2 Answers2

0

Assuming you have equals and hashCode methods overriden in Name class, you can use retainAll method of Set (javadoc here) to find out common elements. E.g.

public static void main(String[] args) throws IOException {
    Set<Name> Names1 = new HashSet<Name>();
    Names1.add(new Name("Jon"));
    Names1.add(new Name("Mark"));
    Names1.add(new Name("Mike"));
    Names1.add(new Name("Helen"));
    Set<Name> Names2 = new HashSet<Name>();
    Names2.add(new Name("Mark"));
    Names2.add(new Name("Mike"));
    Names2.add(new Name("Sally"));

    Names1.retainAll(Names2);

    for(Name name : Names1){
        System.out.println(name.getName());
    }
}

Here's example Name class with equals and hashCode methods:

class Name{
    private String name;

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

    @Override
    public int hashCode(){
        return null != name ? name.hashCode() : 0;
    }

    @Override
    public boolean equals(Object o){
        return o instanceof Name
                && ((Name)o).name != null
                && this.name != null
                && ((Name)o).name.equals(this.name);
    }

    public String getName() {
        return name;
    }
}

Please note that retainAll method modifies the set it's being called on (Names1 in our case). If you want to preserve the original set then you can copy the elements in another set and call retainAll on that instance.

Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
0

Your Set::contains check will not work, because you failed to override Object::equals. The default implementation of Object::equals is checking for reference equality (==), meaning the Name must be the exact same instance to be considered equal.

As others have stated, the correct thing for you to do would be to implement hashCode and equals in your Name class.

Failing that, you would have to iterate through the set and test obj1.getNameString().equals(obj2.getNameString()) to do your own hand-coded and inefficient version of the Set::contains test.

Patrick Parker
  • 4,863
  • 4
  • 19
  • 51