这是我的第一个问题,但我希望我能提供所有必要的信息 如果没有,请告诉我!
我的问题:
我尝试通过添加HashMap来存储已处理的结果来改进我的回溯算法。为此,我为该HashMap的键创建了一个自己的类。在那里我覆盖了.equals() - 和.hashCode() - 方法
但是,如果我试图将这个键及其值放入地图中,则需要花费很多时间,因此算法的效率甚至会低于没有地图的回溯算法。
为了解决这个问题,我将HashMap-Key更改为String并将.toString()方法添加到我的key-class中。这非常好,而且非常快。 (奇怪的是:.toString()。hashCode()会产生很多负值,但似乎有效)
现在我的问题:
如果你创建自己的密钥,它总是会减慢那么多吗?
我试图自己找到这个问题的答案,我发现的唯一的变化是改变.hashCode()或者使用HashMap-Constructor的参数。
我尝试了两个,我为我的测试环境导出了生成的HashCodes,我没有发现任何重复,虽然我知道,它不是哈希码的“好”方法!
这是我的HashKey-Class的副本(变量和方法的名称已更改):
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;
}
}
在我的班级中我使用了这个:
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);
如果我将Key的Type更改为String并将该String放入Map中,它可以正常工作!所以HashKey.hashCode() - 方法和算法的其余部分工作正常并且非常快。
有人知道,我可以做些什么来使用这个HashKey?对于这个算法,它并不重要,但我想知道它的未来算法!
如果有任何问题或批评:非常欢迎!
提前致谢!
Klumbe
答案 0 :(得分:0)
你的课程几乎是不可变的:你所有的实例成员都是最终成员,只是课程本身也需要。
但是,由于所有实例成员都是最终成员,您还可以在构建时计算哈希码:
// Add as member:
private final int hashCode;
public HashKey(int int0, int int1, int int2) {
this.int0 = int0;
this.int1 = int1;
this.int2 = int2;
hashCode = // calculate hash code here
}
public int hashCode()
{
return hashCode;
}
顺便说一句,负哈希码无需担心。毕竟,.hashCode()
会返回一个int。
答案 1 :(得分:0)
试试这个:
简单地使用equals(..)
- 方法,不要多次计算hashCode
。
public final class HashKey {
private final int int0, int1, int2;
private final int hashCode;
public HashKey(int int0, int int1, int int2) {
this.int0 = int0;
this.int1 = int1;
this.int2 = int2;
hashCode=107*int0+227*int1+499*int2;
}
@Override
public final int hashCode() {
return hashCode;
}
@Override
public final boolean equals( finalObject obj) {
if (!obj instanceof HashKey)
retun false;
HashKey other = (HashKey)obj;
return int0 == other.int0 && int1 == other.int1 && int2 == other.int2;
}
}
参考 fge的评论我改变了代码。