Question

I have been at this for days. Our assignment requires that I override the equals() and, more importantly, hashCode(). Objects to be compared: Two-dimensional int arrays.

Criteria of hashCode():

  • Any two-dim array layout that matches any rotated variant or the reflection of the rotated variant should have the same hashCode.

    Visually, that would mean that if I had these two 2d arrays:

    arr 1               arr2
    
    [0, 0, 1]           [1, 0, 0]
    [1, 0, 0]           [0, 0, 1]
    [0, 0, 1]           [1, 0, 0]
    

    The two following print-statements would be identical, since arr2 is a reflection of arr1.

    System.out.println(arr1.hashCode());
    System.out.println(arr2.hashCode());   
    



    Now, I am quite helpless in how to implement this. I figured I would have to do something like this (pseudo):

    int hashCode() {
    
        lastHash = listOfArrays.last().hashCode()
        variants = this.getHashVariants()
    
        foreach (variants as v)
            if (lastHash == v) return v
        return this.SystemGeneratedHash()
    }
    

    There is just so much that can and will go wrong with this approach, but I'm stumped and this was all I could think of. The idea of making the hashCode()-function rely on an outside list feels really icky too. The lecture on the subject was abysmal, and search engines have not been in my favor as of yet.

    Q: How can I make non-identical objects return the same hashCode as long as they match a certain requirement?

  • Was it helpful?

    Solution

    There are several possible solutions to this. Here are four, just off the top of my head -

    • Just return a constant.
    • Add up the numbers in all the cells and return that.
    • Take the absolute value of the determinant of the matrix.
    • Multiply each entry by the distance from the cell to the nearest corner, and add these up.

    This is limited only by your imagination.

    OTHER TIPS

    Well, honestly I would just use Arrays.hashCode(). You need your hashcode to be the same for any rotationally symetric array, so I would write a method which rotates your data 90 degrees, and one which reflects your data. At that point your code is something like:

    public int hashCode() {
        int[][] once = rotate(data);
        int[][] twice = rotate(once);
        int[][] thrice = rotate(twice);
        int[][] flippedData = flip(data);
        int[][] flippedOnce = flip(once);
        int[][] flippedTwice = flip(twice);
        int[][] flippedThrice = flip(thrice);
    
        return Arrays.hashCode(data) + Arrays.hashCode(once) +
               Arrays.hashCode(twice) + Arrays.hashCode(thrice) +
               Arrays.hashCode(flippedData) + Arrays.hashCode(flippedOnce) +
               Arrays.hashCode(flippedTwice) + Arrays.hashCode(flippedThrice);
    }
    

    That way, no matter the original orientation of your data, you still come up with the same ultimate hash code.

    Licensed under: CC-BY-SA with attribution
    Not affiliated with StackOverflow
    scroll top