Assuming you need speed without the overhead of *Set classes, you can write H like this:
public static int H(int list[]) {
It is the same regardless of order, and it is relatively effective.
For instance:
public static void main(String[] args) { System.out.println(Integer.toHexString(H(new int[]{0xabcd,0x1234,0x1111}))); System.out.println(Integer.toHexString(H(new int[]{0x1234,0x1111,0xabcd}))); }
Output:
a8e8 a8e8
This could only be generalized to int by doing the following:
public static int H(Object list[]) {
Then the main program should use Integer arrays instead of the int primitive.
Adding numbers should be just as fast and can give you a better distribution over the 32-bit range. If the elements of the set are already evenly distributed over the range, then xor might be better.
However, with both methods, you can easily create collisions with integers. For example, using the add method;
{1000, 1001, 1002} {0, 1, 3002}
Both of these arrays have the same H() .
Using the XOR method;
{0x1010, 0x0101} {0x1111, 0x0000}
Both of them have the same H() .
Similarly, element 0 problematic since lists will have the same hash with or without it. You can reduce this by adding a constant value at each iteration. For instance:
... hashcode += val.hashCode() + CONSTANT; ...
Or by including the number of elements as the source hash code:
...