Как да избегнем съхраняването на дубликати в Set, ако типът обекти идва от компилиран .class файл?

Опитвам се да съхранявам обекти в Набор, за да избегна дублиране.

Както се обяснява в тази тема Трябва да @Override два метода: hashCode() и equals(Object obj).

Типът обекти, който се опитвам да съхраня в горния Набор идва от компилиран файл .class и няма hashCode() и equals(Object obj) методи и или негови родители във веригата на наследяване (с изключение на Object).

Има ли начин да ги съхраните в комплект, за да избегнете дубликати?


person Robert    schedule 05.02.2021    source източник


Отговори (1)


Ако не можете да модифицирате обектите, можете да ги обвиете.

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<>();
person Louis Wasserman    schedule 05.02.2021
comment
Разбирам, че ще имам Set‹EmployeeHolder›, за да използвам неговите методи hashCode() и equals(Object o), но в крайна сметка ще ми трябва Set‹Employee›. След като Set‹EmployeeHolder› бъде попълнен, ще трябва да го пресека, за да извлека всеки служител. Ако това е правилно, има ли по-ефективен начин да направите това? - person Robert; 06.02.2021
comment
Не, няма. Но защо ви трябва Set<Employee>? Какво можете да направите с него, което не можете да направите с Set<EmployeeHolder>? - person Louis Wasserman; 06.02.2021
comment
Set<Employee> realSet = oldSet.map(EmployeeHolder::getEmployee).collect(Collectors.toSet()); Това ще изисква получател в класа Employee holder. Като алтернатива можете да дублирате методите във вашия Employeeholder клас, за да съответстват на тези от Employee клас. Когато тези методи бъдат извикани, просто предайте извикването на екземпляра Employee и върнете резултата. - person WJS; 06.02.2021
comment
@LouisWasserman Направих някои рефактори и все още използвам някои наследени кодови методи. Тези методи използват специфичен формат на данните Employee в този случай. @WJS За първата част от вашия отговор не исках решение за картографиране. За втората част от вашия отговор, както обясних по-горе, не мога да се отърва от Employee, защото все още се използва в наследения код, с който се занимавам. - person Robert; 06.02.2021
comment
Ако можете да живеете с O(log n) търсене вместо O(1), можете да използвате TreeSet с персонализиран компаратор. Като алтернатива можете да създадете подклас на AbstractSet<Employee>, който делегира на HashSet<EmployeeHolder> за add, size() и contains проверки и имплементира методи като iterator(), използвайки модела, показан от @WJS Нуждаете се само от метода size() и iterator(), за да получите валидна реализация Set, add, за да стане променлив, но contains вече е оптимизация, която е хубаво да имаш. Толкова е просто. - person Holger; 09.02.2021