I need to obtain a set difference between two sets/lists but the objects in these sets are constructed differently. I would like the set difference be calculated on only one field of these objects, how can I do this?
POJO o1 = new POJO();
o1.setName("Bean");
o1.setLocation("Boston");
POJO o2 = new POJO();
o2.setName("Bagel");
o2.setLocation("NYC");
POJO o3 = new POJO();
o3.setName("Bean");
List<POJO> p1 = new ArrayList<>();
p1.add(o1);
p1.add(o2);
List<POJO> p2 = new ArrayList<>();
p2.add(o3);
Collection<POJO> subList = CollectionUtils.subtract(p1, p2);
System.out.println("subList: "+subList.toString());
The output I see is : subList: [POJO(name=Bean)] i.e. o3. But for my use case, o1 and o3 are the same - how can I achieve this? I overrode the default equals() method as well but i don't think it is invoked.
You can achieve this with the help of overloaded subtract with predicate.
Override hashcode and equals in POJO class, (and toString for clean output)
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
POJO pojo = (POJO) o;
return Objects.equals(name, pojo.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
Use Predicate with set as
Collection<POJO> subList = CollectionUtils.subtract(p1, p2, new Predicate<POJO>() {
@Override
public boolean evaluate(POJO object) {
return p1.contains(object); // might need to make p1 final
}
});
Result:
subList: [ Bagel ]
Note: Apache common does not support anything like Java 8 BiPredicate
You can use a UnifiedSetWithHashingStrategy from Eclipse Collections:
POJO o1 = new POJO();
o1.setName("Bean");
o1.setLocation("Boston");
POJO o2 = new POJO();
o2.setName("Bagel");
o2.setLocation("NYC");
POJO o3 = new POJO();
o3.setName("Bean");
HashingStrategy<POJO> strategy = HashingStrategies.fromFunction(POJO::getName);
MutableSet<POJO> set1 =
HashingStrategySets.mutable.with(strategy, o1, o2);
MutableSet<POJO> set2 =
HashingStrategySets.mutable.with(strategy, o3);
MutableSet<POJO> difference = set1.difference(set2);
Assert.assertEquals("[POJO(name=Bagel)]", difference.toString());
This answer explains how UnifiedSetWithHashingStrategy works in more detail.
Note: I am a committer for Eclipse Collections.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With