Nacho321
Nacho321

Reputation: 1991

Asymmetrical difference between sets

I'm working with two sets of data that contain complex java objects that I've created. Let's say that the elements contained are of type People.java, that has a String name and an int age. Let's say I have these sets:

Set1 = [{James, 25}, {Arthur, 18}, {Anne, 22}]

Set2 = [{Arthur, 18}, {James, 25}]

I'm trying to get the asymmetrical difference between set1 and set2 so that the result of that difference is {Anne, 22}. I've tried storing the elements in HashSets and using set1.removeAll(set2), but the answer equals set1. Important to note is that each element is a different instance, meaning that I created a Person object for {James, 25} in set1 and a new Person object for {James, 25} in set2 (there's a reason why they are different instances, since I'm simplifying the project's goal).

I also tried Google's Guava's difference, but the answer remains equal to set1.

I have two questions: 1) Why is that happening? Is is because since they're different instances, the removeAll process considers them to be different? 2) What's a good way to get the asymmetrical difference in this case? I'm guessing using a Comparator, but I'm open to suggestions.

Thanks!

Upvotes: 1

Views: 1966

Answers (3)

arshajii
arshajii

Reputation: 129507

You must have not overrode equals (and/or hashCode), so your Person instances are being compared by reference and not by value. Something like this should do (in the Person class):

@Override
public boolean equals(Object o) {
    if (o instanceof Person) {
        Person p = (Person) o;
        return name.equals(p.name) && age == p.age;
    }
    return false;
}

@Override
public int hashCode() {
    return Arrays.asList(name, age).hashCode();
}

With a proper equals and hashCode, you should be able to simply use set1.removeAll(set2) to get the desired result.

Upvotes: 3

Sanjay Rabari
Sanjay Rabari

Reputation: 2081

Without overriding hasCode() and equals(Object people),

object 1 {Arthur, 18} and object 2{Arthur, 18} with same values will considered different.

when you override below method

public int hashCode()
public boolean equals(Object other)

then such object satify this method will considered same and will occupy the set,

Upvotes: 1

Xabster
Xabster

Reputation: 3720

Your approach is fine, but you probably forgot to

@Override
public int hashCode()

@Override
public boolean equals(Object other)

Upvotes: 1

Related Questions