You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "ivanshuba (via GitHub)" <gi...@apache.org> on 2024/01/16 21:22:07 UTC

[PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

ivanshuba opened a new pull request, #227:
URL: https://github.com/apache/commons-geometry/pull/227

   This commit modifies the `hashCode()` method for `Vector2D` and the `Vector3D` classes in order to ensure unique values are generated for non-identical instances of vectors.
   
   The proposed approach for calculating the hash code value is the same that is used in JTS and HE_Mesh projects. And as quoted in JTS project, this approach was initially 'borrowed' from the Joshua Bloch book 'Effective Java' (1st ed, 2008).
   
   In the "Item 9: Always override hashCode when you override equals" he describes the recipe as follows:
   
   1. Store some constant nonzero value, say 17, in an int variable called `result`.
   2. For each significant field `f` in your object, do the following: a. Compute an int hash code `c` for the field:
         i   ...
         ii  ...
         iii If the field is a long, compute (int)(f^(f>>>32))
         iv  ...
         v   If the field is a double, compute Double.doublToLongBits(f),
             and then hash the resulting long as in step 2.a.iii
         vi  ...
         vii ...
      b. Combine the hash code `c` computed in step 2.a into `result` as
         follows:
           result = 31 * result + c


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "ivanshuba (via GitHub)" <gi...@apache.org>.
ivanshuba commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-1895599122

   @aherbert 
   You're correct this is more readable while keeping the overall approach the same.
   I've checked, and all tests are passing.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "aherbert (via GitHub)" <gi...@apache.org>.
aherbert commented on code in PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#discussion_r1471723996


##########
commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java:
##########
@@ -399,16 +399,24 @@ public boolean eq(final Vector3D vec, final Precision.DoubleEquivalence precisio
 
     /**
      * Get a hashCode for the vector.
-     * <p>All NaN values have the same hash code.</p>

Review Comment:
   Please revert formatting. It ad noise the the changes.



##########
commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java:
##########
@@ -399,16 +399,24 @@ public boolean eq(final Vector3D vec, final Precision.DoubleEquivalence precisio
 
     /**
      * Get a hashCode for the vector.
-     * <p>All NaN values have the same hash code.</p>
-     *
+     * <p>
+     * All NaN values have the same hash code.
      * @return a hash code value for this object
      */
     @Override
     public int hashCode() {
         if (isNaN()) {
             return 642;
         }
-        return 643 * (164 * Double.hashCode(x) + 3 * Double.hashCode(y) + Double.hashCode(z));
+        int result = 17;
+        long temp;
+        temp = Double.doubleToLongBits(x);

Review Comment:
   I thought this was fixed with a different linear combination of `Double.hashCode`. This seems to have reverted to using `doubleToLongBits`.



##########
commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/twod/Vector2D.java:
##########
@@ -340,15 +340,14 @@ public boolean eq(final Vector2D vec, final Precision.DoubleEquivalence precisio
      * Get a hashCode for the 2D coordinates.
      * <p>
      * All NaN values have the same hash code.</p>
-     *

Review Comment:
   Revert formatting



##########
commons-geometry-spherical/src/test/java/org/apache/commons/geometry/spherical/twod/GreatCircleTest.java:
##########
@@ -664,7 +664,7 @@ void testHashCode() {
         Assertions.assertEquals(hash, a.hashCode());
 
         Assertions.assertNotEquals(hash, b.hashCode());
-        Assertions.assertNotEquals(hash, c.hashCode());
+        Assertions.assertEquals(hash, c.hashCode());

Review Comment:
   If the two circles are the same then this should be tested using `Assertions.assertEquals`. If they are the same then the hash code **_must_** be the same. If the objects are not equal then the hash code may or may not collide; it doesn't matter.
   
   Any test that uses not equals on hash codes for objects that are not equal can potentially fail due to random hash collision.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "ivanshuba (via GitHub)" <gi...@apache.org>.
ivanshuba commented on code in PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#discussion_r1471307137


##########
commons-geometry-spherical/src/main/java/org/apache/commons/geometry/spherical/twod/GreatCircle.java:
##########
@@ -338,7 +338,17 @@ public boolean eq(final GreatCircle other, final Precision.DoubleEquivalence pre
     /** {@inheritDoc} */
     @Override
     public int hashCode() {
-        return Objects.hash(pole, u, v, getPrecision());
+        int result = 1;
+        long temp;

Review Comment:
   > I think the current implementation is fine. What should be changed is the test. 
   
   At present, there is only one assertion causing the test to fail. For these two circles:
   ```java
   final GreatCircle c = GreatCircles.fromPoleAndU(Vector3D.Unit.PLUS_Z, Vector3D.Unit.MINUS_X, TEST_PRECISION);
   final GreatCircle a = GreatCircles.fromPoleAndU(Vector3D.Unit.PLUS_Z, Vector3D.Unit.PLUS_X, TEST_PRECISION);
   ```
   
   The test currently assumes the hashes must not be equal.
   ```java
   final int hash = a.hashCode();
   Assertions.assertNotEquals(hash, c.hashCode());
   ```
   
   I might be misunderstanding this point ( please help me clarify ), but it appears that these two circles are topologically identical meaning they occupy the same space.
   
   If this interpretation is correct, we could simply modify the assumption and assert that the hashes of these two circles are expected to be the same.
   
   ```java
   Assertions.assertEquals(hash, c.hashCode());
   ```
   
   With this small adjustment, the test should pass.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "ivanshuba (via GitHub)" <gi...@apache.org>.
ivanshuba commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-1895590560

   @aherbert You're right, that is more readable and does the same. 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "ivanshuba (via GitHub)" <gi...@apache.org>.
ivanshuba commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-1898973285

   @aherbert 
   
   `GreatCircle` class was using the `Objects.hash()` wrapper method to calculate hash value. In its turn, it was calling the `Arrays.hashCode()` method. 
   
   Unfortunately, somewhere during the process, this fails to prevent hash collisions when it's calculated for the `GreatCircle` instances. I haven't investigated the cause yet. As a guess, this might be related to that the `Precision.DoubleEquivalence`'s `hashCode()` method is not overridden, not sure.
   
   Anyways, the usage of the same approach as in `Vector2D` and `Vector3D` classes resolves the issue for the `GreatCircle` also.
   
   ```java
   @Override
   public int hashCode() {
       int result = 1;
       long temp;
       temp = pole.hashCode();
       result = 31 * result + (int) (temp ^ (temp >>> 32));
       temp = u.hashCode();
       result = 31 * result + (int) (temp ^ (temp >>> 32));
       temp = v.hashCode();
       result = 31 * result + (int) (temp ^ (temp >>> 32));
       temp = getPrecision().hashCode();
       result = 31 * result + (int) (temp ^ (temp >>> 32));
       return result;
   }
   ```
   
   
   
   Additionally, I fixed my incorrect indentations and variable naming added previously to prevent check errors.
   
   _All_ tests are passing now when I run them through Maven.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "aherbert (via GitHub)" <gi...@apache.org>.
aherbert commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-2081374502

   The changes I requested to the tests have not been implemented. Without them the tests **could** sporadically fail.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "aherbert (via GitHub)" <gi...@apache.org>.
aherbert commented on code in PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#discussion_r1499188481


##########
commons-geometry-euclidean/src/main/java/org/apache/commons/geometry/euclidean/threed/Vector3D.java:
##########
@@ -339,6 +339,7 @@ public Vector3D reject(final Vector3D base) {
      * frame with one of the axes in a predefined direction. The
      * following example shows how to build a frame having the k axis
      * aligned with the known vector u :
+     *

Review Comment:
   Undo this formatting.



##########
commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java:
##########
@@ -1146,6 +1145,65 @@ void testEqualsAndHashCode_signedZeroConsistency() {
         Assertions.assertEquals(b.hashCode(), d.hashCode());
     }
 
+    @Test
+    void testHashCodeCollisions_symmetricAboutZero() {
+        final double any = Math.random();

Review Comment:
   Note that this could create sporadic failures. We can formalise this using some random numbers:
   ```java
   @ParameterizedTest
   @ValueSource(doubles = {1.23, 4.56, 42, Math.PI})
   void testHashCodeCollisions_symmetricAboutZero(double any) {
   ```



##########
commons-geometry-spherical/src/test/java/org/apache/commons/geometry/spherical/twod/GreatCircleTest.java:
##########
@@ -664,7 +664,7 @@ void testHashCode() {
         Assertions.assertEquals(hash, a.hashCode());
 
         Assertions.assertNotEquals(hash, b.hashCode());
-        Assertions.assertNotEquals(hash, c.hashCode());
+        Assertions.assertEquals(hash, c.hashCode());

Review Comment:
   If this is testing the hash codes are equal (because the objects are equal) then we should test the objects are equal:
   ```java
   // Equal objects have equal hash codes
   Assertions.assertEquals(a, c);
   Assertions.assertEquals(hash, c.hashCode());
   ```



##########
commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java:
##########
@@ -23,7 +23,6 @@
 import java.util.Comparator;
 import java.util.List;
 import java.util.regex.Pattern;
-

Review Comment:
   Undo this formatting.



##########
commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java:
##########
@@ -1146,6 +1145,65 @@ void testEqualsAndHashCode_signedZeroConsistency() {
         Assertions.assertEquals(b.hashCode(), d.hashCode());
     }
 
+    @Test
+    void testHashCodeCollisions_symmetricAboutZero() {
+        final double any = Math.random();
+        final double neg = -any;
+        final double pos = +any;
+
+        final Vector3D negX = Vector3D.of(neg, 0.0, 0.0);
+        final Vector3D posX = Vector3D.of(pos, 0.0, 0.0);
+        final Vector3D negY = Vector3D.of(0.0, neg, 0.0);
+        final Vector3D posY = Vector3D.of(0.0, pos, 0.0);
+        final Vector3D negZ = Vector3D.of(0.0, 0.0, neg);
+        final Vector3D posZ = Vector3D.of(0.0, 0.0, pos);
+
+        int xNegHash = negX.hashCode();
+        int xPosHash = posX.hashCode();
+        int yNegHash = negY.hashCode();
+        int yPosHash = posY.hashCode();
+        int zNegHash = negZ.hashCode();
+        int zPosHash = posZ.hashCode();
+
+        String xMessage = String.format("negXHash: %s, posXHash: %s (expected to be non-equal)\n", xNegHash, xPosHash);
+        String yMessage = String.format("negYHash: %s, posYHash: %s (expected to be non-equal)\n", yNegHash, yPosHash);
+        String zMessage = String.format("negZHash: %s, posZHash: %s (expected to be non-equal)\n", zNegHash, zPosHash);
+
+        Assertions.assertNotEquals(zNegHash, zPosHash, zMessage);
+        Assertions.assertNotEquals(yNegHash, yPosHash, yMessage);
+        Assertions.assertNotEquals(xNegHash, xPosHash, xMessage);
+    }
+
+    @Test
+    void testHashCodeCollisions_symmetricAboutArbitraryValue() {

Review Comment:
   Same as  testHashCodeCollisions_symmetricAboutZero. Use a ParameterizedTest and simplify the assertion message.
   ```java
   @ParameterizedTest
   @CsvSource(
      "1.23, 72.68",
      // etc
   )
   void testHashCodeCollisions_symmetricAboutArbitraryValue(double any, double arb) {
   ```



##########
commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java:
##########
@@ -1146,6 +1145,65 @@ void testEqualsAndHashCode_signedZeroConsistency() {
         Assertions.assertEquals(b.hashCode(), d.hashCode());
     }
 
+    @Test
+    void testHashCodeCollisions_symmetricAboutZero() {
+        final double any = Math.random();
+        final double neg = -any;
+        final double pos = +any;
+
+        final Vector3D negX = Vector3D.of(neg, 0.0, 0.0);
+        final Vector3D posX = Vector3D.of(pos, 0.0, 0.0);
+        final Vector3D negY = Vector3D.of(0.0, neg, 0.0);
+        final Vector3D posY = Vector3D.of(0.0, pos, 0.0);
+        final Vector3D negZ = Vector3D.of(0.0, 0.0, neg);
+        final Vector3D posZ = Vector3D.of(0.0, 0.0, pos);
+
+        int xNegHash = negX.hashCode();
+        int xPosHash = posX.hashCode();
+        int yNegHash = negY.hashCode();
+        int yPosHash = posY.hashCode();
+        int zNegHash = negZ.hashCode();
+        int zPosHash = posZ.hashCode();
+
+        String xMessage = String.format("negXHash: %s, posXHash: %s (expected to be non-equal)\n", xNegHash, xPosHash);
+        String yMessage = String.format("negYHash: %s, posYHash: %s (expected to be non-equal)\n", yNegHash, yPosHash);
+        String zMessage = String.format("negZHash: %s, posZHash: %s (expected to be non-equal)\n", zNegHash, zPosHash);
+
+        Assertions.assertNotEquals(zNegHash, zPosHash, zMessage);

Review Comment:
   Why are these in z, y, x order? Makes more sense to use x, y, z, order.



##########
commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/twod/Vector2DTest.java:
##########
@@ -912,6 +911,53 @@ void testHashCode() {
         Assertions.assertEquals(Vector2D.of(0, Double.NaN).hashCode(), Vector2D.of(Double.NaN, 0).hashCode());
     }
 
+    @Test
+    void testHashCodeCollisions_symmetricAboutZero() {

Review Comment:
   Same as previous. Use a ParameterizedTest and simplify the assertion message.



##########
commons-geometry-euclidean/src/test/java/org/apache/commons/geometry/euclidean/threed/Vector3DTest.java:
##########
@@ -1146,6 +1145,65 @@ void testEqualsAndHashCode_signedZeroConsistency() {
         Assertions.assertEquals(b.hashCode(), d.hashCode());
     }
 
+    @Test
+    void testHashCodeCollisions_symmetricAboutZero() {
+        final double any = Math.random();
+        final double neg = -any;
+        final double pos = +any;
+
+        final Vector3D negX = Vector3D.of(neg, 0.0, 0.0);
+        final Vector3D posX = Vector3D.of(pos, 0.0, 0.0);
+        final Vector3D negY = Vector3D.of(0.0, neg, 0.0);
+        final Vector3D posY = Vector3D.of(0.0, pos, 0.0);
+        final Vector3D negZ = Vector3D.of(0.0, 0.0, neg);
+        final Vector3D posZ = Vector3D.of(0.0, 0.0, pos);
+
+        int xNegHash = negX.hashCode();
+        int xPosHash = posX.hashCode();
+        int yNegHash = negY.hashCode();
+        int yPosHash = posY.hashCode();
+        int zNegHash = negZ.hashCode();
+        int zPosHash = posZ.hashCode();
+
+        String xMessage = String.format("negXHash: %s, posXHash: %s (expected to be non-equal)\n", xNegHash, xPosHash);

Review Comment:
   These should be passed a suppliers to Assertions. However the Assertions will already have a statement containing the two values and that they were expected to be not equal. So we can just use:
   ```java
   Assertions.assertNotEquals(zNegHash, zPosHash, "+/- z hash");
   ```
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "aherbert (via GitHub)" <gi...@apache.org>.
aherbert commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-2761931564

   These hashcode changes have been integrated into the master branch.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "ivanshuba (via GitHub)" <gi...@apache.org>.
ivanshuba commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-1959345545

   Hi @aherbert 
   
   Can I ask if you want me to fix anything to get this moving on?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "ivanshuba (via GitHub)" <gi...@apache.org>.
ivanshuba commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-1896191100

   > I've checked, and all tests are passing.
   
   @aherbert Well, not all apparently. Only the ones I've added.
   
   I'll try to find out what causes the `GreatCircleTest` to fail.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "aherbert (via GitHub)" <gi...@apache.org>.
aherbert closed pull request #227: Fix hash code collision for Vector2D and Vector3D
URL: https://github.com/apache/commons-geometry/pull/227


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "darkma773r (via GitHub)" <gi...@apache.org>.
darkma773r commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-2081272864

   Even later to the party here... :-)
   
   @singhbaljit, I would be on board with trying out EqualsVerifier. We already have [GEOMETRY-107](https://issues.apache.org/jira/projects/GEOMETRY/issues/GEOMETRY-107) for this.
   
   @aherbert, @ivanshuba, we are still waiting on the requested changes, correct?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "singhbaljit (via GitHub)" <gi...@apache.org>.
singhbaljit commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-1959502218

   A little late to the party, but I think we should consider using https://github.com/jqno/equalsverifier to test `hashCode` and `equals` in a standard way, instead of writing all different permutations in the tests.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "aherbert (via GitHub)" <gi...@apache.org>.
aherbert commented on PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#issuecomment-1895461155

   I would use `int Double.hashCode(double)` which effectively does the same thing but does not require as many statements, e.g.
   ```java
       public int hashCode() {
           if (isNaN()) {
               return 642;
           }
           int result = Double.hashCode(x);
           result = 31 * result + Double.hashCode(y);
           result = 31 * result + Double.hashCode(z);
           return result;
       }
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Fix hash code collision for Vector2D and Vector3D [commons-geometry]

Posted by "aherbert (via GitHub)" <gi...@apache.org>.
aherbert commented on code in PR #227:
URL: https://github.com/apache/commons-geometry/pull/227#discussion_r1457926790


##########
commons-geometry-spherical/src/main/java/org/apache/commons/geometry/spherical/twod/GreatCircle.java:
##########
@@ -338,7 +338,17 @@ public boolean eq(final GreatCircle other, final Precision.DoubleEquivalence pre
     /** {@inheritDoc} */
     @Override
     public int hashCode() {
-        return Objects.hash(pole, u, v, getPrecision());
+        int result = 1;
+        long temp;

Review Comment:
   `temp` does not have to be a `long` here since all the `hashCode()` methods will return an `int`. As such all the xor shift folding is effectively just randomly flipping the bits based on the sign since `(temp >>> 32) == 0` for positive or `-1` (32-bits set) for negative `int` hash codes. The xor operation then flips the original int bits if they were negative.
   
   The fact that this works over using Object.hashCode is that some of the hashCodes are negative. So your implementation uses these bit flipped before the addition and the hash is different, but still random.
   
   I think the current implementation is fine. What should be changed is the test. This is assuming that non equal objects will have different hash codes. This is not true. The only contract is that equal objects have equal hash codes.
   
   Since the hash code for the 3-D vectors use the xyx coordinates, using unit vectors results in some of the hash codes being the same. Perhaps try updating the vectors for objects b, c, d to use random xyz coords. The following lines should then pass (unless you are very unlucky with your random vectors).
   
   ```java
           // Probably true (unless we are unlucky with the hashes of the vectors)
           Assertions.assertNotEquals(hash, b.hashCode());
           Assertions.assertNotEquals(hash, c.hashCode());
           Assertions.assertNotEquals(hash, d.hashCode());
   ```
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@commons.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org