2

hi i've seen this post how to implement the union and intersection when it you have two sets of data,that are strings.how can i do the same when my sets contain objects,and i want to get the union of only one property of each object?

Community
  • 1
  • 1
user1746708
  • 691
  • 1
  • 8
  • 16

4 Answers4

2

But I want to override them somehow so that it wont add an object if there's an object already in my set that has the same value in a selected property.If i'm not clear enough tell me so i can write an example.

I think the best way to do this is to use a ConcurrentMap.

ConcurrentMap<String, MyType> map = new ConcurrentHashMap<>();

// the collection to retain.
for(MyType mt: retainedSet) map.put(mt.getKey(), mt);

// the collection to keep if not duplicated
for(MyType mt: onlyIfNewSet) map.putIfAbsent(mt.getKey(), mt);

// to get the intersection.
Set<String> toKeep = new HashSet<>();
for(MyType mt: onlyIfNewSet) toKeep.add(mt.getKey());

// keep only the keys which match.
map.keySet().retainAll(toKeep);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • well it look okay,thanks but i'm sorry ican't figure out how's this works.I mean i guess MyType is my custom object,But how can i chose based on what field should the union and instersection should be done? – user1746708 Dec 20 '12 at 09:45
  • The "MyType" is your custom type and the "getKey()" is the field you want to key on. – Peter Lawrey Dec 20 '12 at 10:14
  • 1
    Ok i've used your snippet it workd like a dream litteraly.Thank you for passing the knowledge. – user1746708 Dec 20 '12 at 19:31
1

Google Guava, has Sets class which contains these methods and many more.

Amir Pashazadeh
  • 7,170
  • 3
  • 39
  • 69
0

Intersection is using contains, which uses equals. You should implement equals() method on the class that you want to do intersection.

I didn't find specific comments about set.addAll() implementation, but most probably it also uses equals() to determine if an object is already on the set.

If you want to compare only by a field, your equals() should only compare this field.

dgmora
  • 1,239
  • 11
  • 27
  • ok i figured it was somethiing like this,but you see i'm more interested right now on the union side.you're sure i should again override the equals()? – user1746708 Dec 20 '12 at 09:23
  • Java uses always equals() to see if to objects are equals, and addAll() specification says it performs union (http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Collection.html#addAll%28java.util.Collection%29). I don't see any reason to consider a different behavior – dgmora Dec 20 '12 at 09:29
0

As in this answer, use Collection methods retainAll(Collection)- intersection and #addAll(Collection)- union.

Since those methods use equals, you also have to override equals method in your Class and implement one-property based comparison.

In case it's simple comparison, here's an example (generated by my IDEA):

public class Main {

private Integer age;

...

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Main main = (Main) o;

    if (age != null ? !age.equals(main.age) : main.age != null) return false;

    return true;
}
Community
  • 1
  • 1
tadaskay
  • 111
  • 4
  • ok i had somehting like that in my mind but how can i override equals() properly? – user1746708 Dec 20 '12 at 09:47
  • I updated the answer with an example. If you want dig in further about `equals`, [here is a good answer](http://stackoverflow.com/a/27609/760484). – tadaskay Dec 20 '12 at 10:04