Java 从字符串和int创建哈希
我记得eclipse和idea使用这个模板根据对象的属性自动创建对象的哈希代码 如果使用数字和字符串,其中一种策略是这样的Java 从字符串和int创建哈希,java,eclipse,hash,code-generation,intellij-idea,Java,Eclipse,Hash,Code Generation,Intellij Idea,我记得eclipse和idea使用这个模板根据对象的属性自动创建对象的哈希代码 如果使用数字和字符串,其中一种策略是这样的 return stringValue.hashCode() + intValue * 32; 等等 我手头没有eclipse或idea,我想创建这样的函数 编辑 基于这些答案,我创建了这个小型课程 class StringInt { private final String s; private final int i;
return stringValue.hashCode() + intValue * 32;
等等
我手头没有eclipse或idea,我想创建这样的函数
编辑
基于这些答案,我创建了这个小型课程
class StringInt {
private final String s;
private final int i;
static StringInt valueOf( String string , int value ) {
return new StringInt( string, value );
}
private StringInt( String string, int value ) {
this.s = string;
this.i = value;
}
public boolean equals( Object o ) {
if( o != null && o instanceof StringInt ){
StringInt other = ( StringInt ) o;
return this.s == other.s && this.i == other.i;
}
return false;
}
public int hashCode() {
return s != null ? s.hashCode() * 37 + i : i;
}
}
这个类将用作大型内存映射(>10k个元素)的键,我不想每次都迭代它们来查找字符串和int是否相同
多谢各位
附言。。嗯,可能应该是名称StringIntKey。使用Apache Commons HashcodeBuilder:
public int hashCode() {
new HashCodeBuilder(17, 37).
append(myString).
append(myInt);
}
链接此处:
在这里:
或者,如果不想添加其他库,请执行以下操作:
public int hashCode() {
StringBuilder builder = new StringBuilder();
builder.append(myString);
builder.append(myInteger);
return builder.toString().hashCode();
}
Eclipse总是执行大致相同的哈希函数,下面是一个以in和字符串作为字段的类的示例
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + this.interger;
result = prime * result + ((this.string == null) ? 0 : this.string.hashCode());
return result;
}
他们总是选择31作为素数,然后根据内置哈希函数或原语的值进行倍数。像这样的东西作为一种方法并不难创造
public int hashCode(Object ... things) {
final int prime = 31;
int result = 1;
for(Object thing : things) {
result = prime * result + thing.hashCode();
}
return result;
}
除了最近的编辑之外,如果检索速度比存储问题更重要,那么在构建
StringInt
类时,可以预先计算并存储哈希代码。这是安全的,因为您已将String
和int
字段标记为final
,而且String
是不可变的
此外,在进行完全比较之前,您可以通过检查要比较的对象==this
来优化equals
方法。我还建议在比较字符串字段之前先进行基于int的比较
另一个最后的建议是:您可以将
valueOf(String,int)
方法更改为构造StringInt
或返回以前创建的实例(如果已有一个实例具有相同的String
和int值)。这使得构造更加昂贵,但比较非常便宜,因为您可以使用“==”来比较StringInt
s,因为您知道不会用相同的String
和int
值创建两个StringInt
s,因此值得优化。如果计算复杂,请考虑对哈希值进行记忆。此外,避免做需要更多计算的事情。(例如,StringBuilder解决方案将大部分时间用于创建临时字符串。)
我想指出的另一件事是散列的质量很重要。您希望避免任何映射许多公共密钥的哈希代码算法。如果发生这种情况,哈希表查找可能不再是O(1)。(在最坏的情况下,它将是O(N)…即等同于线性搜索!)。下面是一个错误哈希函数的示例:
int hashcode() {
int hash = 1;
for (int val : this.values) {
hash = hash * value;
}
return hash;
}
考虑一下如果
this.values
的元素为零会发生什么…您还可以使用java.util.Objects
包中的对象
类快速获取哈希代码
@Override
public int hashCode() {
return Objects.hash(this.string, this.integerValue, this.otherDataTypes);
}
HashCodeBuilder源代码在线吗。我来看看,上面写着:string.hashCode*37+intValue!!我受够了!!谢谢你!。。有时我会错过这种解决方案!!是的,我不想再添加一个库。谢谢你的邀请advice@aperkins:只写“return(myString+myInteger).hashCode()”更简单。Java编译器将把它编译成等效的StringBuilder.append调用序列。@perkins:另一件事,如果你真的关心速度,那么这种方法比计算和组合组件hashcodes要慢得多。hashCode应该很快,最好是使用字符串的哈希代码,并对整数进行简单的整数数学运算。速度问题可能是正确的,但我从未注意到在我们编写的代码中使用此方法会显著降低速度。通常,我们对性能的关注更多地与电汇或算法更改有关。奥斯卡,我认为这是一门好课。hashCode方法清晰、可靠且性能良好。如何防止字符串为空?在构造函数中,如果NPE为null,则抛出它。然后可以删除equals和hashCode中的空保护。最后,为这些问题准备一份“有效Java”。Eclipse和IDEA创建的hashCode方法就是基于这本书的。