You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2022/11/05 08:47:08 UTC

[commons-collections] branch master updated: Remove Comparable from the Shape class

This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a6665af3 Remove Comparable from the Shape class
9a6665af3 is described below

commit 9a6665af3657bf548b8bbd62b82fa12cd39e5af0
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sat Nov 5 08:43:58 2022 +0000

    Remove Comparable from the Shape class
    
    The Shape could be used as a key so implements equals and hashCode. The
    ordering of a Shape is arbitrary.
---
 .../commons/collections4/bloomfilter/Shape.java    | 23 ++++++-------
 .../collections4/bloomfilter/ShapeTest.java        | 40 +++++++++++++++-------
 2 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java b/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
index d39df255e..2632fedac 100644
--- a/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
+++ b/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
@@ -16,8 +16,6 @@
  */
 package org.apache.commons.collections4.bloomfilter;
 
-import java.util.Objects;
-
 /**
  * The definition of a Bloom filter shape.
  *
@@ -43,7 +41,7 @@ import java.util.Objects;
  * [Wikipedia]</a>
  * @since 4.5
  */
-public final class Shape implements Comparable<Shape> {
+public final class Shape {
 
     /**
      * The natural logarithm of 2. Used in several calculations. Approximately 0.693147180559945.
@@ -81,19 +79,20 @@ public final class Shape implements Comparable<Shape> {
     }
 
     @Override
-    public int compareTo(Shape other) {
-        int i = Integer.compare(numberOfBits, other.numberOfBits);
-        return i == 0 ? Integer.compare(numberOfHashFunctions, other.numberOfHashFunctions) : i;
-    }
-
-    @Override
-    public boolean equals(final Object o) {
-        return (o instanceof Shape) ? compareTo((Shape) o) == 0 : false;
+    public boolean equals(Object obj) {
+        // Shape is final so no check for the same class as inheritance is not possible
+        if (obj instanceof Shape) {
+            Shape other = (Shape) obj;
+            return numberOfBits == other.numberOfBits &&
+                   numberOfHashFunctions == other.numberOfHashFunctions;
+        }
+        return false;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(numberOfBits, numberOfHashFunctions);
+        // Match Arrays.hashCode(new int[] {numberOfBits, numberOfHashFunctions})
+        return (31 + numberOfBits) * 31 + numberOfHashFunctions;
     }
 
     /**
diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/ShapeTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/ShapeTest.java
index ecafa2ef4..e87535c9c 100644
--- a/src/test/java/org/apache/commons/collections4/bloomfilter/ShapeTest.java
+++ b/src/test/java/org/apache/commons/collections4/bloomfilter/ShapeTest.java
@@ -17,11 +17,16 @@
 package org.apache.commons.collections4.bloomfilter;
 
 import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Arrays;
+
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
 
 /**
  * Tests the {@link Shape} class.
@@ -45,18 +50,29 @@ public class ShapeTest {
     /**
      * Test equality of shape.
      */
-    @Test
-    public void testEquals() {
-
-        assertEquals(shape, shape);
-        assertEquals(3, shape.getNumberOfHashFunctions());
-        assertEquals(24, shape.getNumberOfBits());
-        assertEquals(shape.hashCode(), Shape.fromKM(3, 24).hashCode());
-        assertNotEquals(shape, null);
-        assertNotEquals(shape, Shape.fromKM(3, 25));
-        assertNotEquals(shape, Shape.fromKM(4, 24));
-        assertNotEquals(shape, "text");
-        assertNotEquals(shape, Integer.valueOf(3));
+    @ParameterizedTest
+    @CsvSource({
+        "3, 24",
+        "1, 24",
+        "1, 1",
+        "13, 124",
+        "13, 224",
+    })
+    public void testEqualsAndHashCode(int k, int m) {
+        Shape shape1 = Shape.fromKM(k, m);
+        assertEquals(shape1, shape1);
+        assertEquals(Arrays.hashCode(new int[] {m, k}), shape1.hashCode(),
+            "Doesn't match Arrays.hashCode(new int[] {m, k})");
+        assertNotEquals(shape1, null);
+        assertNotEquals(shape1, "text");
+        assertNotEquals(shape1, Integer.valueOf(3));
+        assertNotEquals(shape1, Shape.fromKM(k, m + 1));
+        assertNotEquals(shape1, Shape.fromKM(k + 1, m));
+
+        // Test this is reproducible
+        Shape shape2 = Shape.fromKM(k, m);
+        assertEquals(shape1, shape2);
+        assertEquals(shape1.hashCode(), shape2.hashCode());
     }
 
     @Test