Skip to content

Commit f493213

Browse files
committed
[kubernetes] Fix Quantity.hashCode to honor equals/hashCode contract
Quantity.equals compares the underlying BigDecimal by value (ObjectUtils.compare -> BigDecimal.compareTo, scale-insensitive), but hashCode used Objects.hash(number) which is scale-sensitive. Value-equal quantities such as "1" and "1000m" (1.000) are therefore equal yet produce different hash codes, breaking HashMap/HashSet lookups. Normalize the scale with BigDecimal.stripTrailingZeros() before hashing so the hash is consistent with the value-based equals. Adds a focused unit test (fails before, passes after).
1 parent 7f36a85 commit f493213

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

‎kubernetes/src/main/java/io/kubernetes/client/custom/Quantity.java‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ public boolean equals(Object o) {
9090

9191
@Override
9292
public int hashCode() {
93-
return Objects.hash(number);
93+
// equals() compares numbers by value (scale-insensitive via BigDecimal.compareTo), so the
94+
// hash must also be scale-insensitive to honor the equals/hashCode contract. Normalize the
95+
// scale before hashing; otherwise e.g. "1" and "1000m" are equal but hash differently.
96+
return Objects.hash(number == null ? null : number.stripTrailingZeros());
9497
}
9598

9699
public static class QuantityAdapter extends TypeAdapter<Quantity> {

‎kubernetes/src/test/java/io/kubernetes/client/custom/QuantityTest.java‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,17 @@ void containsInSet() {
3030

3131
assertEquals(set1, set2, "Sets of equal elements are not equal");
3232
}
33+
34+
@Test
35+
void equalQuantitiesWithDifferentScaleHaveEqualHashCode() {
36+
// "1" parses to scale 0; "1000m" parses to 1000 * 10^-3 = 1.000 (scale 3). They are equal by
37+
// value, so the equals/hashCode contract requires equal hash codes (and HashSet membership).
38+
final Quantity a = Quantity.fromString("1");
39+
final Quantity b = Quantity.fromString("1000m");
40+
41+
assertEquals(a, b, "quantities with the same value should be equal");
42+
assertEquals(
43+
a.hashCode(), b.hashCode(), "equal quantities must have equal hash codes (equals/hashCode contract)");
44+
assertEquals(Set.of(a), Set.of(b), "equal quantities must be interchangeable as hash-set members");
45+
}
3346
}

0 commit comments

Comments
 (0)