use*_*908 5 java equals hashcode bigdecimal lombok
我有这里描述的问题。这是因为BigDecimalare等于被破坏,所以在类中具有这样的字段会阻止使用@EqualsAndHashCode。我想出的唯一解决方案就是针对exclude此类领域,但这当然不是最佳选择。
有什么解决办法吗?有什么办法为字段/类型注入自己的比较器?
我最近遇到了同样的问题。
基本上,您会看到以下行为:
BigDecimal x = new BigDecimal("2");
BigDecimal y = new BigDecimal("2.00");
System.out.println(x.equals(y)); // False
System.out.println(x.compareTo(y) == 0 ? "true": "false"); // True
Run Code Online (Sandbox Code Playgroud)
没有开箱即用的好解决方案,但您可以重新定义 hashCode 和 equals 中使用的 BigDecimal 字段值:
@EqualsAndHashCode
class Test Class {
@EqualsAndHashCode.Exclude
private BigDecimal amount;
...
@EqualsAndHashCode.Include
private BigDecimal getAmountForEquals() {
return ofNullable(amount).map(BigDecimal::stripTrailingZeros).orElse(null);
}
}
Run Code Online (Sandbox Code Playgroud)
BigDecimal好吧,它 \xe2\x80\x99s 不是 Lombok\xe2\x80\x99s 的错误,因为一般情况下还不清楚如何比较。无论如何,下面的示例代码提供了一个解决方案:
import lombok.AccessLevel;\nimport lombok.AllArgsConstructor;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport lombok.Getter;\nimport lombok.Setter;\nimport lombok.ToString;\n\nimport java.math.BigDecimal;\n\n@Data\n@AllArgsConstructor\npublic class WithBigDecimals {\n\n private int i;\n\n private String s;\n\n @EqualsAndHashCode.Exclude\n private BigDecimal d;\n\n @Getter(AccessLevel.NONE)\n @Setter(AccessLevel.NONE)\n @ToString.Exclude\n private final BigDecimalComparer _bdc = new BigDecimalComparer();\n\n private class BigDecimalComparer {\n public WithBigDecimals getOuter() {\n return WithBigDecimals.this;\n }\n\n @Override\n public boolean equals(Object obj) {\n if (!(obj instanceof BigDecimalComparer))\n return false;\n BigDecimalComparer other = (BigDecimalComparer) obj;\n double epsilon = d.doubleValue() / 1000d;\n return d.doubleValue() - epsilon < other.getOuter().d.doubleValue() &&\n other.getOuter().d.doubleValue() < d.doubleValue() + epsilon;\n }\n }\n\n public static void main(String[] args) {\n var a = new WithBigDecimals(42, "2.4", new BigDecimal("2.4"));\n var b = new WithBigDecimals(42, "2.4", new BigDecimal("2.40"));\n var c = new WithBigDecimals(42, "2.4", new BigDecimal(2.4));\n\n System.out.printf("%s == %s ?? %b%n", a, b, a.equals(b));\n System.out.printf("%s == %s ?? %b%n", b, c, b.equals(c));\n System.out.printf("%s == %s ?? %b%n", a, c, a.equals(c));\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n\n如您所见, 被BigDecimal排除在外@EqualsAndHashCode。为了重新注入它,我创建了另一个只能私人访问的字段。用于自动生成的equals()方法,可以随意提供比较。我在这里使用了一个简单版本的几乎相等。
| 归档时间: |
|
| 查看次数: |
1001 次 |
| 最近记录: |