1

I am trying to store objects in a Set to avoid duplicates.

As this topic explains I need to @Override two methods: hashCode() and equals(Object obj).

The objects type that I am trying to store in the above Set comes from a compiled .class file and it doesn't have hashCode() and equals(Object obj) methods and either it's parents on inheritance chain (except Object).

Is there a way to store them in a Set to avoid duplicates?

Robert
  • 186
  • 3
  • 6
  • 16

1 Answers1

2

If you cannot modify the objects, then you can wrap them.

class EmployeeHolder {
  private final Employee employee;
  public int hashCode() { ... }
  public boolean equals(Object o) {
    if (!(o instanceof EmployeeHolder)) return false;
    ...
  }
}
Set<EmployeeHolder> set = new HashSet<>();
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • I understand that I will have a Set to use its hashCode() and equals(Object o) methods, but in the end I will need a Set. After Set is populated I will have to cross it to extract each Employee. If this is right, is any more efficient way to do this? – Robert Feb 05 '21 at 22:06
  • 2
    No, there isn't. But _why_ do you need a `Set`? What can you do with it that you can't do with a `Set`? – Louis Wasserman Feb 05 '21 at 22:50
  • `Set realSet = oldSet.map(EmployeeHolder::getEmployee).collect(Collectors.toSet());` This will require a getter in the Employee holder class. As an alternative you can duplicate the methods in your `Employeeholder` class to match those of the `Employee` class. When those methods are called, just pass the call to the `Employee` instance and return the result. – WJS Feb 05 '21 at 22:51
  • @LouisWasserman I did some refactor and I'm still using some legacy code methods. Those methods use a specific format of data `Employee` in this case. @WJS For the first part of your answer I wasn't asking for a mapping solution. For the second part of your answer as I explained above, I cannot get rid of `Employee` because it is still used in legacy code I'm dealing with. – Robert Feb 06 '21 at 06:55
  • 2
    If you can live with O(log n) lookup rather than O(1) lookup, you can use a `TreeSet` with a custom comparator. Alternatively, you can create a subclass of `AbstractSet` that delegates to a `HashSet` for `add`, `size()`, and `contains` checks and implements methods like `iterator()` using the pattern shown by @WJS You only need the `size()` method and the `iterator()` to get a valid `Set` implementation, `add` to make it mutable, but `contains` is already a nice-to-have optimizations. It’s as simple as that. – Holger Feb 09 '21 at 13:18