Java 从字符串和整数创建哈希

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1209633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:56:24  来源:igfitidea点击:

Create hash from string and int

javaeclipsehashcode-generationintellij-idea

提问by OscarRyz

I remember eclipse and idea have this template to automatically create an object's hashCode based on its attributes.

我记得 eclipse 和 idea 有这个模板可以根据对象的属性自动创建对象的 hashCode。

One of the strategies if a number and a string is used is something like this.

如果使用数字和字符串,其中一种策略是这样的。

  return stringValue.hashCode() + intValue * 32;

Ooor something like that.

Ooor类似的东西。

I don't have nor eclipse or idea at hand and I would like to create such function.

我手头没有,也没有日食或想法,我想创建这样的功能。

EDIT

编辑

Based on the answers I create this mini-class

根据答案我创建了这个迷你课程

    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;
        }
    }

This class is to be used as key for a large memory map ( > 10k elements ) I don't want to iterate them each time to find if the String and the int are the same.

此类将用作大型内存映射(> 10k 个元素)的键,我不想每次都迭代它们以查找 String 和 int 是否相同。

Thank you.

谢谢你。

ps.. mmh probably it should be names StringIntKey.

ps.. mmh 可能应该是名称 StringIntKey。

采纳答案by Jon

回答by aperkins

Or, if you don't want to add another library, do something like the following:

或者,如果您不想添加另一个库,请执行以下操作:

public int hashCode() {
    StringBuilder builder = new StringBuilder();
    builder.append(myString);
    builder.append(myInteger);
    return builder.toString().hashCode();
}

回答by Patrick Auld

Eclipse always does roughly the same hashing function, here's an example for a class with an in and String as fields

Eclipse 总是执行大致相同的散列函数,这是一个以 in 和 String 作为字段的类的示例

    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;
    }

They always pick 31 as the prime, and then multiple by build in hash functions or the value if its a primitive. Something like this wouldn't be hard to create as a method.

他们总是选择 31 作为质数,然后通过内置的哈希函数或值(如果它是一个原始值)乘以倍数。像这样的东西作为一种方法来创建并不难。

     public int hashCode(Object ... things) {
         final int prime = 31;
         int result = 1;
         for(Object thing : things) {
             result = prime * result + thing.hashCode();
         }
         return result;
     }

回答by Adamski

Further to your most recent edit, if retrieval speed is more important than storage concerns you could pre-compute and store the hash code when constructing your StringIntclass. This is safe as you've marked the Stringand intfields as final, and also given that Stringis immutable.

除了您最近的编辑,如果检索速度比存储问题更重要,您可以在构建StringInt类时预先计算并存储哈希码。这是安全的,因为您已将Stringint字段标记为final,并且它String是不可变的。

Also, you could optimise your equalsmethod by checking that the object being compared == thisbefore doing a full comparison. I would also recommend doing the cheaper int-based comparison first before comparing the string fields.

此外,您可以equals通过this在进行完整比较之前检查正在比较的对象 ==来优化您的方法。我还建议在比较字符串字段之前先进行更便宜的基于 int 的比较。

Another final suggestion: You could change your valueOf(String, int)method to either construct a StringIntor return a previously created instance if one already exists with the same Stringand int values. This makes construction more expensive but comparisons very cheap as you can compare StringInts using "==" in the knowledge that no two StringInts will ever be created with the same Stringand intvalue.

另一个最后的建议:如果已经存在具有相同和 int 值的实例,您可以将valueOf(String, int)方法更改为构造一个StringInt或返回一个先前创建的实例String。这使得构造更昂贵,但比较非常便宜,因为您可以StringInt使用“==”比较s,因为知道不会StringInt创建两个具有相同Stringint值的s 。

回答by Stephen C

A hashcode method is something that potentially be called many times, and is therefore worth optimizing. If the calculation is complicated, consider memoizing the hash value. Also, avoid doing things that entail more calculation than is necessary. (For example, the StringBuilder solution spends most of its time creating the temporary String.)

哈希码方法可能会被多次调用,因此值得优化。如果计算复杂,可以考虑记忆哈希值。此外,避免做需要更多计算的事情。(例如,StringBuilder 解决方案花费大部分时间来创建临时字符串。)

The other thing I want to point out is that the quality of the hash is important. You want to avoid any hashcode algorithm that maps lots of common keys. If that happens, hash table lookup may no longer be O(1). (In the worst case it will be O(N) ... i.e. equivalent to a linear search!). Here's an example of a bad hash function:

我想指出的另一件事是散列的质量很重要。您希望避免任何映射大量公共键的哈希码算法。如果发生这种情况,哈希表查找可能不再是 O(1)。(在最坏的情况下,它将是 O(N) ... 即相当于线性搜索!)。下面是一个错误的散列函数的例子:

int hashcode() {
    int hash = 1;
    for (int val : this.values) {
        hash = hash * value;
    }
    return hash;
}

Consider what happens if an element of this.valuesis zero ...

考虑如果 的元素this.values为零会发生什么......

回答by Puneeth Reddy V

You can also use Objectsclass from java.util.Objectspackage to quickly get hash code.

您还可以使用包中的Objectsjava.util.Objects来快速获取哈希码。

@Override
public int hashCode() {
    return Objects.hash(this.string, this.integerValue, this.otherDataTypes);
}