Add object to a set using multiple fields as equality comparison to overrride existing equals and hashCode methods

Viewed 91

I have a POJO class that already has equals and hashcode defined and used for many legacy objects that are saved to a DB so changing how that object works is not an option.

Her's a simplified code:

@EqualsAndHashCode(of = {"id"}, callSuper = false)
public class BenefitContract {

    private static final Logger LOGGER = LoggerFactory.getLogger(BenefitContract.class);

    @Id
    @GeneratedValue(generator = "ss_benefit_contract_sequence", strategy = GenerationType.SEQUENCE)
    @Column(name = "SS_BENEFIT_CONTRACT_ID")
    private Long id;

    private UUID guid;

    private Benefit benefit;

    private LocalDate startDate;

    private BigDecimal contractCost;

    ...
    private static Set<BenefitContract> uniqueContracts;

    ...
}   

So, I want to add benefit contracts to the uniqueContracts based on employee, startDate and contractCost so as to eliminate duplicate contracts for the same employee based on these fields.

How that could be done given I can't re-define equals and hashcode?

1 Answers

I ended up implementing an ugly old-style "Comparator" method as follows. That checks if an element duplicates any other already in the set and then adds the element for real:

    private boolean addToSet(BenefitContract contract) {
        for (BenefitContract bc : uniqueContracts) {
            if (isEqual(contract, bc)) {
                return false;
            }
        }
        uniqueContracts.add(contract);
        return true;
    }

    private boolean isEqual(BenefitContract t, BenefitContract t1) {
        if (t == t1) {
            return true;
        }
        if (Objects.equals(t.getGuid(), t1.getGuid())) {
            return true;
        }
        if (Objects.equals(t.getBenefit(), t1.getBenefit()) &&
                Objects.equals(t.getContractCost(), t1.getContractCost()) &&
                Objects.equals(t.getStartDate(), t1.getStartDate())) {
            return true;
        }
        return false;
    }
 
    //A method that actually does some processing
    private process(BenefitContract contract){
        ...
        addToSet(bc);
    }

      ...
}

Surely it can be prettyfied using Java 8 etc, but that'll come later

Related