lombok equalsandhashcode检查类类型吗

sczxawaw  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(321)

lombok@equalsandhashcode是否检查类类型/示例?
编辑:我想提到的是,我在一家拥有自己框架的大公司工作,就像许多其他公司一样,我们只限于此。我没有能力在我们的框架之外添加库,因为我们的安全需要非常严格(你们中的许多人在你们的州没有电)。所以lombok最近刚刚被引入到我们的框架中(版本1.18.12,直到2月20日才发布),Java8也被引入到我们的框架中,这是我正在使用的代码和库的另一个例子。因此,请原谅我,如果我不是非常精通Lombok山或我从来没有听说过德龙,直到它被提到在评论。
回到问题上来:
我读过https://projectlombok.org/features/equalsandhashcode 有几次我得出了不同的结论。
下面是一个我正在做的帮助澄清我的问题的例子:

@Entity
@Table(name = GeneratorTypeA.VIEW)
@Getter
@Setter
@ToString
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
public class GeneratorTypeA extends AbstractGenerator {
    ...
    @Id
    @EqualsAndHashCode.Include
    @SequenceGenerator(...)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "GeneratorA.seq.id")
    @Column(name = "GENERATOR_A_ID", precision = 19, scale = 0)
    private Long id;
    ...
}

generatortypeb看起来与上面的代码段完全相同。现在假设我有以下几点:

final Set<GeneratorTypeA> generatorsA = ...;
final Set<GeneratorTypeB> generatorsB = ...;

每个实体仅在“id”参数上使用@equalsandhashcode.include。我使用下面的代码将集合和集合合并为一个集合。因为我只显式地写了唯一id应该用于equals,所以当我合并它们时,我可能会丢失两个集合中的实体,除非lombok还比较每个对象的“示例”。那么,有人知道lombok是否执行此检查(onlyexplicitlyincluded设置为true-或一般情况下),或者是否有方法通过添加此检查来使用lombok吗?
我想在没有Lombok山的情况下使用等效等于法:

public boolean equals(final Object other) {
    if (!(other instanceof GeneratorTypeA)) {
        return false;
    }
    final GeneratorTypeA castOther = (GeneratorTypeA) other;
    return new EqualsBuilder().append(getId(), castOther.getId()).isEquals();
}

我用来组合这些集合的代码在这个设置中运行得很好,但是我处理了大量数据,因此遇到equals方法中使用的重复唯一标识符的可能性非常低,但是它为意外的功能/错误打开了大门。

public static <T> Set<?> combine(final Set<?>... sets) {
    return Stream.of(sets).flatMap(Set::stream).collect(Collectors.toSet());
}
wz1wpwve

wz1wpwve1#

lombok可以很好地生成equals和hashcode,您不必担心。但是,当您重写equals和hashcode并且在hash类型集合中使用这些对象时,您应该小心,并且(这一点很重要)这些对象不是不可变的。那么你可能会得到意想不到的结果。让我举一个具体的例子:

public class SetTest  {

    @Getter
    @Setter
    @AllArgsConstructor
    @EqualsAndHashCode
    @ToString
    static class User {
        private String name;
        private int age;
    }

    public static void main(String[] args) {
        Set<User> users = new HashSet<>();
        User user1 = new User("Jane", 25);
        User user2 = new User("John", 40);
        users.add(user1);
        users.add(user2);

        user1.setAge(26);
        users.add(user1);

        System.out.println(users);
    }
}

回答: [Task.SetTest.User(name=Jane, age=26), Task.SetTest.User(name=Jane, age=26), Task.SetTest.User(name=John, age=40)] 如您所见,现在您在集合中有3个对象,而不是2个。这是因为实现了从hashset添加,其工作方式如下:
添加新对象时,将计算哈希代码
哈希码,标识保存具有相同哈希码的所有对象(冲突对象)的bucket
对该bucket中的所有对象(如果存在)执行循环,并将这些对象与equals进行比较
如果新添加的对象与bucket中的一个对象匹配,则该对象不会添加到集合中,否则会添加
在我的例子中,在我更改了用户jane的年龄之后,我更改了hashcode的值,并且该对象被添加到集合中,因为集合中不存在具有相同hashcode的其他对象。

dy1byipe

dy1byipe2#

对;对象必须是的示例 this 班级。
根据文件:

if (!(o instanceof EqualsAndHashCodeExample)) return false;

另一方面,具有讽刺意味的是,您的公司显然是如此重视安全,以至于它选择在采用Java1.8之前等待很多年,但它却等待了这么久,以至于1.8在您采用它之前就已经是生命的终结,而且支持已经终止,使您暴露在未修补的安全漏洞中。

相关问题