this is my first question here, but i hope i will provide all the needed information.
If NOT, please let me know!
My Problem:
I tried to improve my backtracking-algorithm by adding a HashMap to store the already processed results. For this i created a own class for the key of that HashMap. In there i overwrote the .equals()- and .hashCode()- methods.
But if i try to put this key and it’s value into the map, it is taking much time, so that the algorithm becomes even less efficient then the backtrack-algorithm without the map.
To solve that problem, i changed the HashMap-Key to String and addded a .toString()-method to my key-class. This works very fine and it is quite fast. (Strange thing: .toString().hashCode() produces a lot of negative values, but seems to work)
Now my Question:
Is it always slowing down that much, if you create your own key?
I tried to find a answer to that question on my own and the only thin i found was to change .hashCode() or playing with the parameters of the HashMap-Constructor.
I tried both and i exported the produced HashCodes for my test-environment and i did not find any duplicates, though i know, it isn’t a “good” method for hash-codes!
Here is a copy of my HashKey-Class (names of variables and methods changed):
public class HashKey {
private final int int0, int1, int2;
public HashKey(int int0, int int1, int int2) {
this.int0 = int0;
this.int1 = int1;
this.int2 = int2;
}
public int getInt0() {
return this.int0;
}
public int getInt1() {
return this.int1;
}
public int getInt2() {
return this.int2;
}
@Override
public int hashCode() {
final int prime1 = 107;
final int prime2 = 227;
final int prime3 = 499;
int result = 1;
result = prime1 * result + this.int2;
result = prime2 * result + this.int1;
result = prime3 * result + this.int0;
return result;
}
@Override
public String toString() {
return "Int0: " + this.int0 + " Int1: " + int1 + " Int2: " + int2;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof HashKey) {
boolean eq0, eq1, eq2;
eq0 = this.int0 == ((HashKey) obj).getInt0();
eq1 = this.int1 == ((HashKey) obj).getInt1();
eq2 = this.int2 == ((HashKey) obj).getInt2();
if (eq0 && eq1 && eq2) {
return true;
}
}
return false;
}
}
And in my main-Class i use this:
HashMap<HashKey, List<Object>> storedResults = new HashMap<HashKey, List<Object>>();
int x1,x2,x3;
Object obj;
// later in a method:
storedResults.put(new HashKey(x1,x2,x3), obj);
If i change the Type of the Key to String and put that String into the Map, it works fine! So the HashKey.hashCode()-method and the rest of the algorithm works fine and is quite fast.
Does anybody know, what i can do to use this HashKey? For this algorithm it is not that important, but i want to know it for future algorithms!
If there are any questions or critics: they are VERY welcome!
Thanks in advance!
Klumbe
Try this:
Simplyfy your
equals(..)-method and do not calculate thehashCodemore than once.Referring to the comment of fge I changed the code.