0
class Object {
  string name;
  Time date;
  string createdBy;
  int version;
}

How do I merge two sets of Objects, with the requirement that if an object from Set1 has matching name and version as an object from Set2, keep only the one from Set2 in the resulting merged set.

E.g.

Set1: { Object1(name:wilson, date:00:00:00, createdBy:admin, version:1), Object2(name:wilson, date:00:00:00, createdBy:admin, version:2) }

Set2: { Object3(name:arizona, date:00:00:00, createdBy:user, version:5), Object4(name:wilson, date:00:00:00, createdBy:user, version:1) }

With the resulting merged set: { Object4(name:wilson, date:00:00:00, createdBy:user, version:1), Object2(name:wilson, date:00:00:00, createdBy:admin, version:2), Object3(name:arizona, date:00:00:00, createdBy:user, version:5), } (ordering doesn't matter)

I can union the two sets and but I'm not sure how to take advantage of Java 8 streams to add this filtering condition

  • merge and then find [`distinctByKey`](https://stackoverflow.com/questions/23699371/java-8-distinct-by-property). – Naman Nov 11 '20 at 06:44

1 Answers1

0

If you consider your objects to be equal if the name and version is the same then you could define that as your equality test (i.e. override equals and hashcode in your class).

If you have defined that condition as equals then it's a simple matter of storing the collections in a set:

Set<Object> mergedSet = new HashSet(set2);
mergedSet.addAll(set1);

Notice I added set2 first so that the objects there take precedence.

If this is a special condition and not generally representative of equal objects, then:

Set<Object> mergedSet = new HashSet(set2);
set1.stream()
    .filter(o1 -> set2.stream()
        .noneMatch(o2 -> o1.name.equals(o2.name) && o1.version == o2.version))
    .forEach(mergedSet::add);
sprinter
  • 27,148
  • 6
  • 47
  • 78