`
小网客
  • 浏览: 1241058 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

把string映射到64位的hashcode值方法

 
阅读更多

可以参考 xmemcached 的实现,源码如下:

 

public enum HashAlgorithm {

        /**
         * Native hash (String.hashCode()).
         */
        NATIVE_HASH,
        /**
         * CRC32_HASH as used by the perl API. This will be more consistent both
         * across multiple API users as well as java versions, but is mostly likely
         * significantly slower.
         */
        CRC32_HASH,
        /**
         * FNV hashes are designed to be fast while maintaining a low collision
         * rate. The FNV speed allows one to quickly hash lots of data while
         * maintaining a reasonable collision rate.
         * 
         * @see http://www.isthe.com/chongo/tech/comp/fnv/
         * @see http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash
         */
        FNV1_64_HASH,
        /**
         * Variation of FNV.
         */
        FNV1A_64_HASH,
        /**
         * 32-bit FNV1.
         */
        FNV1_32_HASH,
        /**
         * 32-bit FNV1a.
         */
        FNV1A_32_HASH,
        /**
         * MD5-based hash algorithm used by ketama.
         */
        KETAMA_HASH,

        /**
         * From mysql source
         */
        MYSQL_HASH,

        ELF_HASH,

        RS_HASH,

        /**
         * From lua source,it is used for long key
         */
        LUA_HASH,

        ELECTION_HASH,
        /**
         * The Jenkins One-at-a-time hash ,please see
         * http://www.burtleburtle.net/bob/hash/doobs.html
         */
        ONE_AT_A_TIME;

        private static final long FNV_64_INIT = 0xcbf29ce484222325L;
        private static final long FNV_64_PRIME = 0x100000001b3L;

        private static final long FNV_32_INIT = 2166136261L;
        private static final long FNV_32_PRIME = 16777619;

        /**
         * Compute the hash for the given key.
         * 
         * @return a positive integer hash
         */
        public long hash(final String k) {
                long rv = 0;
                switch (this) {
                case NATIVE_HASH:
                        rv = k.hashCode();
                        break;
                case CRC32_HASH:
                        // return (crc32(shift) >> 16) & 0x7fff;
                        CRC32 crc32 = new CRC32();
                        crc32.update(ByteUtils.getBytes(k));
                        rv = crc32.getValue() >> 16 & 0x7fff;
                        break;
                case FNV1_64_HASH: {
                        // Thanks to pierre@demartines.com for the pointer
                        rv = FNV_64_INIT;
                        int len = k.length();
                        for (int i = 0; i < len; i++) {
                                rv *= FNV_64_PRIME;
                                rv ^= k.charAt(i);
                        }
                }
                        break;
                case FNV1A_64_HASH: {
                        rv = FNV_64_INIT;
                        int len = k.length();
                        for (int i = 0; i < len; i++) {
                                rv ^= k.charAt(i);
                                rv *= FNV_64_PRIME;
                        }
                }
                        break;
                case FNV1_32_HASH: {
                        rv = FNV_32_INIT;
                        int len = k.length();
                        for (int i = 0; i < len; i++) {
                                rv *= FNV_32_PRIME;
                                rv ^= k.charAt(i);
                        }
                }
                        break;
                case FNV1A_32_HASH: {
                        rv = FNV_32_INIT;
                        int len = k.length();
                        for (int i = 0; i < len; i++) {
                                rv ^= k.charAt(i);
                                rv *= FNV_32_PRIME;
                        }
                }
                        break;
                case ELECTION_HASH:
                case KETAMA_HASH:
                        byte[] bKey = computeMd5(k);
                        rv = (long) (bKey[3] & 0xFF) << 24 | (long) (bKey[2] & 0xFF) << 16
                                        | (long) (bKey[1] & 0xFF) << 8 | bKey[0] & 0xFF;
                        break;

                case MYSQL_HASH:
                        int nr2 = 4;
                        for (int i = 0; i < k.length(); i++) {
                                rv ^= ((rv & 63) + nr2) * k.charAt(i) + (rv << 8);
                                nr2 += 3;
                        }
                        break;
                case ELF_HASH:
                        long x = 0;
                        for (int i = 0; i < k.length(); i++) {
                                rv = (rv << 4) + k.charAt(i);
                                if ((x = rv & 0xF0000000L) != 0) {
                                        rv ^= x >> 24;
                                        rv &= ~x;
                                }
                        }
                        rv = rv & 0x7FFFFFFF;
                        break;
                case RS_HASH:
                        long b = 378551;
                        long a = 63689;
                        for (int i = 0; i < k.length(); i++) {
                                rv = rv * a + k.charAt(i);
                                a *= b;
                        }
                        rv = rv & 0x7FFFFFFF;
                        break;
                case LUA_HASH:
                        int step = (k.length() >> 5) + 1;
                        rv = k.length();
                        for (int len = k.length(); len >= step; len -= step) {
                                rv = rv ^ (rv << 5) + (rv >> 2) + k.charAt(len - 1);
                        }
                case ONE_AT_A_TIME:
                        try {
                                int hash = 0;
                                for (byte bt : k.getBytes("utf-8")) {
                                        hash += (bt & 0xFF);
                                        hash += (hash << 10);
                                        hash ^= (hash >>> 6);
                                }
                                hash += (hash << 3);
                                hash ^= (hash >>> 11);
                                hash += (hash << 15);
                                return hash;
                        } catch (UnsupportedEncodingException e) {
                                throw new IllegalStateException("Hash function error", e);
                        }
                default:
                        assert false;
                }

                return rv & 0xffffffffL; /* Truncate to 32-bits */
        }

        /**
         * Get the md5 of the given key.
         */
        public static byte[] computeMd5(String k) {
                MessageDigest md5;
                try {
                        md5 = MessageDigest.getInstance("MD5");
                } catch (NoSuchAlgorithmException e) {
                        throw new RuntimeException("MD5 not supported", e);
                }
                md5.reset();
                md5.update(ByteUtils.getBytes(k));
                return md5.digest();
        }

        // public static void main(String[] args) {
        // HashAlgorithm alg=HashAlgorithm.CRC32_HASH;
        // long h=0;
        // long start=System.currentTimeMillis();
        // for(int i=0;i<100000;i++)
        // h=alg.hash("MYSQL_HASH");
        // System.out.println(System.currentTimeMillis()-start);
        // }
}
1
4
分享到:
评论

相关推荐

    hashcode的作用

    在Java中,`hashCode()` 方法是 `Object` 类的一个重要成员方法,它返回一个整数,这个整数通常用来表示对象的哈希值。哈希值在Java集合框架中扮演着至关重要的角色,尤其是在散列表(如 `HashMap` 和 `Hashtable`)...

    hashcode与eqault比较

    2. **避免返回固定值**:不要在`hashCode`方法中总是返回一个固定的值,比如0,这会导致所有的对象都映射到同一个哈希桶中,从而降低哈希表的性能。 3. **考虑效率**:在实现`hashCode`时,应该尽可能地让不同的对象...

    hashcode和equals的分析

    ### hashCode和equals方法详解 #### 一、hashCode方法解析 在深入探讨`hashCode`方法之前,我们需要了解Java集合框架的基本概念。Java集合框架主要包括两大类集合:`List`和`Set`。 - **List**:这是一个有序集合...

    java中的哈希算法和hashcode深入讲解1

    "java中的哈希算法和hashcode深入讲解" 哈希算法是计算机领域中非常重要的一种技术,它具有非常广泛的应用,例如快速查找和加密。哈希算法可以将任意长度的...最终,我们可以得到String类的hashCode值,也就是哈希值。

    JAVA hashCode使用方法详解

    综上所述,理解和正确使用 `hashCode()` 和 `equals()` 方法对于编写高效且符合预期的Java代码至关重要,特别是在处理集合和映射数据结构时。遵循良好的重写规范可以提高容器的性能,并避免潜在的错误。

    javahashcode()和equals()和==的介绍和区别.pdf

    首先,`hashCode()`是一个方法,存在于Java的`Object`类中,其目的是为了提供一种快速的哈希算法,将对象映射到一个整数值。这个值通常用于哈希表,如Java的`HashMap`或`HashSet`,以确定对象在内部存储的位置。哈希...

    java中的hashCode方法小例子

    哈希码(Hash Code)是一个对象的唯一标识,它将对象映射到一个整数,使得通过哈希码可以在哈希表中快速定位对象。 根据Java的`equals()`和`hashCode()`约定,如果两个对象`equals()`比较返回`true`,那么这两个...

    Hibernate注解映射联合主键

    在这种映射方式中,联合主键的字段被放在一个单独的类中,这个类需要实现`java.io.Serializable`接口并重写`equals()`和`hashCode()`方法,以确保对象的唯一性。然后,这个类被注解为`@Embeddable`。在主类中,我们...

    java中hashcode()和equals()的详解.docx

    ### Java中`hashCode()`与`equals()`方法详解 #### 前言 在Java编程语言中,`hashCode()`和`equals()`方法是非常重要的概念,它们主要用于处理对象的唯一标识和对象之间的相等性判断。正确地实现这两个方法对于确保...

    hibernate映射Oracle中LONG类型

    例如,在保存数据时,我们可以使用 CustomLong 类的 nullSafeSet 方法将 LONG 类型字段的值写入到数据库中。 使用自定义类型映射 Oracle 中的 LONG 类型字段有很多优点。首先,它可以解决 LONG 类型字段的读写问题...

    HashTableProgram:使用String键的常规Hash映射程序

    在Java中,String类已经重写了`hashCode()`方法,因此我们可以直接用String对象作为键来创建哈希映射。`HashTableProgram`可能是用来演示如何创建和操作一个包含String键的哈希表的程序。下面我们将深入探讨相关的...

    mysql数据库表映射实体生成

    MySQL数据库表映射实体生成是一种常见的开发任务,特别是在Java企业级应用中,它涉及到ORM(对象关系映射)技术,如Hibernate或MyBatis。这个工具类的目标是自动化将数据库中的表结构转换为编程语言中的实体类,这样...

    HashSet去重

    `HashSet`通过调用对象的`hashCode()`方法来获取哈希码,然后根据哈希码将对象映射到哈希表的一个位置。 - **`equals`方法**:当`HashSet`检测到两个对象的哈希码相同时,会进一步调用这两个对象的`equals()`方法来...

    Dictionary字典详解

    * 添加元素:使用Add()方法添加键-值对到字典中。 * 查看字典元素:使用索引器[]来访问字典中的元素。 * 修改字典元素:使用索引器[]来访问字典中的元素,并赋值新的值。 * 删除字典元素:使用Remove()方法删除字典...

    一名java培训生的学习笔记(基础部分2).docx

    ### Java培训生学习笔记知识点梳理 ...通过上述知识点梳理,我们可以了解到`HashMap`的基本操作以及如何在自定义类中重写`equals`和`hashCode`方法来支持基于内容的比较。这对于理解Java集合框架的工作原理至关重要。

    day06-集合1

    哈希值主要用于快速查找对象,因为哈希表(如HashSet)是通过哈希函数将对象映射到数组的特定位置。 3. **如何获取哈希值** 要获取对象的哈希值,可以调用该对象的`hashCode()`方法。例如,在`SetDemo`示例中,...

    java中HashMap详解.pdf

    为了找到对应的数组位置,HashMap使用了indexFor()方法,该方法通过将散列值与数组长度减一进行按位与操作来得到索引值: ```java static int indexFor(int hash, int length) { return hash & (length - 1); } ``...

    HashMap原理.docx

    当我们通过`put(key, value)`方法向HashMap中添加元素时,HashMap会先对键调用`hashCode()`方法获得哈希值,再通过特定的哈希算法计算出对应的数组索引。这样可以快速定位到具体的存储位置,从而实现高效的插入和...

    2020年面试题.docx

    - 散列存储是一种查找技术,其目的是通过一种确定的方式将数据元素的关键码映射到存储位置上,从而实现高效的数据访问。 - 在散列存储中,每个对象都有一个唯一的物理地址,这个地址经过散列函数计算后生成一个散列...

    188道java面试题

    它允许开发者使用面向对象的方式来操作数据库,通过XML或注解配置来映射对象到数据库表。 10. **JVM内存模型**: JVM内存分为堆内存、栈内存、方法区、程序计数器和本地方法栈。堆内存存储对象实例,栈内存存储...

Global site tag (gtag.js) - Google Analytics