Java 使用多个字段作为相等比较将对象添加到集合中,以覆盖现有的equals和hashCode方法

Java 使用多个字段作为相等比较将对象添加到集合中,以覆盖现有的equals和hashCode方法,java,collections,set,compare,Java,Collections,Set,Compare,我有一个POJO类,它已经定义了equals和hashcode,并用于许多保存到DB中的遗留对象,因此更改该对象的工作方式不是一个选项 她的代码是一个简化的代码: @EqualsAndHashCode(of = {"id"}, callSuper = false) public class BenefitContract { private static final Logger LOGGER = LoggerFactory.getLogger(BenefitCon

我有一个POJO类,它已经定义了equals和hashcode,并用于许多保存到DB中的遗留对象,因此更改该对象的工作方式不是一个选项

她的代码是一个简化的代码:

@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;

    ...
}   
@EqualsAndHashCode(of={“id”},callSuper=false)
公共福利合同{
私有静态最终记录器Logger=LoggerFactory.getLogger(BenefitContract.class);
@身份证
@GeneratedValue(generator=“ss_福利_合同_顺序”,策略=GenerationType.sequence)
@列(name=“SS\U福利\U合同\U ID”)
私人长id;
专用UUID guid;
私人利益;
私有LocalDate开始日期;
私人成本;
...
私有静态集唯一合同;
...
}   
因此,我想根据employee、startDate和contractCost将福利合同添加到
uniqueContracts
,以消除基于这些字段的相同员工的重复合同


如果我不能重新定义equals和hashcode,那该怎么做呢?

我最终实现了一个丑陋的老式“Comparator”方法,如下所示。检查一个元素是否与集合中已有的任何其他元素重复,然后实际添加该元素:

    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);
    }

      ...
}

当然,可以使用Java8等对其进行预处理,但这将在稍后进行

Holger,很好。实际上,我的代码做了一些稍微不同的事情,但我已经逐字添加了它。我已经调整了此处发布的代码,以便与您的评论保持一致。请注意,
Set.add
的约定是,如果已添加参数,则返回
true
,即之前不在集合中,如果参数已存在,则返回
false
。建议在其他方法中也遵循此模式。