Lombok EqualsAndHashCode 是否检查 Class 类型
Does Lombok EqualsAndHashCode Check Class Type
Lombok @EqualsAndHashCode 是否检查 class type/instance?
编辑:我想提一下,我在一家拥有自己框架的大公司工作,就像许多其他公司一样,我们受到限制。由于我们的安全需要多么密集(你们中的许多人在你们所在的州没有电),我无法在我们的框架之外添加图书馆。所以 Lombok 最近才被引入我们的框架(版本 1.18.12,直到 2 月 20 日才发布)Java 8 给你另一个我正在使用的例子和 code/libraries 我可能已经接触到了。因此,如果我对 Lombok 不是很精通,或者在评论中提到它之前我从未听说过 Delombok,请原谅我。
回到问题:
我读过 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。我正在使用下面的代码将 Set 和 Set 组合成一个 Set。因为我只是明确地写了唯一的 id 应该用于相等,所以当我组合它们时我可能会丢失两个集合中的实体,除非 Lombok 也比较每个对象的“实例”。那么有谁知道 Lombok 是否执行此检查(将 onlyExplicitlyIncluded 设置为 true - 或一般情况下)或者是否有一种方法可以通过添加此检查来利用 Lombok?
我想在没有 Lombok 的情况下使用等效的 equals 方法:
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 方法中使用的重复唯一标识符的机会是非常低,但它为意外打开了大门 functionality/bugs。
public static <T> Set<?> combine(final Set<?>... sets) {
return Stream.of(sets).flatMap(Set::stream).collect(Collectors.toSet());
}
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 以这种方式执行添加:
- 添加新对象时,会计算哈希码
- 哈希码,标识所有具有相同哈希码的对象(冲突对象)所在的桶
- 对该桶(如果存在)中的所有对象进行循环,并将对象与等值进行比较
- 如果新添加的对象与桶中的对象之一匹配,则该对象不添加到集合中,否则添加
在我的例子中,在我更改用户 Jane 的年龄后,我更改了 hashcode 的值,并且该对象被添加到集合中,因为集合中不存在具有相同 hashcode 的其他对象。
是;该对象必须是 this
class.
的实例
根据 documentation:
if (!(o instanceof EqualsAndHashCodeExample)) return false;
顺便说一句,具有讽刺意味的是,您的公司显然如此注重安全,以至于选择等待多年才采用 java 1.8,但等待的时间太长以至于 1.8 已经停产 在您采用它之前并且支持已经终止,使您暴露在未修补的安全漏洞之下。
Lombok @EqualsAndHashCode 是否检查 class type/instance?
编辑:我想提一下,我在一家拥有自己框架的大公司工作,就像许多其他公司一样,我们受到限制。由于我们的安全需要多么密集(你们中的许多人在你们所在的州没有电),我无法在我们的框架之外添加图书馆。所以 Lombok 最近才被引入我们的框架(版本 1.18.12,直到 2 月 20 日才发布)Java 8 给你另一个我正在使用的例子和 code/libraries 我可能已经接触到了。因此,如果我对 Lombok 不是很精通,或者在评论中提到它之前我从未听说过 Delombok,请原谅我。
回到问题:
我读过 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。我正在使用下面的代码将 Set 和 Set 组合成一个 Set。因为我只是明确地写了唯一的 id 应该用于相等,所以当我组合它们时我可能会丢失两个集合中的实体,除非 Lombok 也比较每个对象的“实例”。那么有谁知道 Lombok 是否执行此检查(将 onlyExplicitlyIncluded 设置为 true - 或一般情况下)或者是否有一种方法可以通过添加此检查来利用 Lombok?
我想在没有 Lombok 的情况下使用等效的 equals 方法:
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 方法中使用的重复唯一标识符的机会是非常低,但它为意外打开了大门 functionality/bugs。
public static <T> Set<?> combine(final Set<?>... sets) {
return Stream.of(sets).flatMap(Set::stream).collect(Collectors.toSet());
}
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 以这种方式执行添加:
- 添加新对象时,会计算哈希码
- 哈希码,标识所有具有相同哈希码的对象(冲突对象)所在的桶
- 对该桶(如果存在)中的所有对象进行循环,并将对象与等值进行比较
- 如果新添加的对象与桶中的对象之一匹配,则该对象不添加到集合中,否则添加
在我的例子中,在我更改用户 Jane 的年龄后,我更改了 hashcode 的值,并且该对象被添加到集合中,因为集合中不存在具有相同 hashcode 的其他对象。
是;该对象必须是 this
class.
根据 documentation:
if (!(o instanceof EqualsAndHashCodeExample)) return false;
顺便说一句,具有讽刺意味的是,您的公司显然如此注重安全,以至于选择等待多年才采用 java 1.8,但等待的时间太长以至于 1.8 已经停产 在您采用它之前并且支持已经终止,使您暴露在未修补的安全漏洞之下。