【问题标题】:Java hash utilitiesJava 哈希实用程序
【发布时间】:2012-03-07 07:44:56
【问题描述】:

我正在寻找一个好的 hash 实用程序框架 来将字符串映射到范围内的某个 int 值,例如 {1 .. k} 我应该在运行时组件中使用它,该组件接收来自用户的大量并发请求,'userId' 是字符串,我想将该值映射到定义的整数范围。

当然,userId 值的长度可能不同,但我可以假设使用此函数的最小长度

应该很快

谢谢

【问题讨论】:

  • 你是在为一个哈希表做一个哈希,还是一​​个唯一的 ID?
  • 当两个用户标识映射到同一个整数时会发生什么?这称为“碰撞”,必须加以处理。 String.hashCode() 已经完成了合理的工作,您可以通过 str.hashCode()%k + 1 将结果放入 {1..k}
  • 但我看到了问题——这不起作用,因为哈希码是供参考的,因此两个相同的字符串将得到不同的哈希码` public static void main(String[] args) { Scanner input=new Scanner (系统.in); System.out.println("请输入字符串:");字符串 str1=input.nextLine(); System.out.println("请输入字符串:");字符串 str2=input.nextLine(); System.out.println(str1.hashCode() + " " + str2.hashCode()); } ` 这是输出:
  • @Julias 那是不正确的。建议你看一下String.hashCode()的代码,或者自己试试。
  • 如果您想添加代码和示例,我建议您在问题中包含此内容。注释不能很好地处理代码。 :(

标签: java performance


【解决方案1】:

每个 Java 对象都有一个内置的hashCode 方法,该方法返回一个int。对于String,它是为您预定义的(需要为自定义对象实现)。

要将其映射到1..k,其中 k 是整数,请考虑使用模数:

String hi = "Hello";
int hash = (hi.hashCode() % K) + 1;

【讨论】:

  • hashCode() 返回 int 而不是 long
  • 所有天才的想法都是最简单的 :-) 谢谢,我会有良好的价值观分布吗?
  • 请注意,使用 % 会破坏大概均匀的 hashCode 分布。你可以考虑用除法来缩放它。
  • hashCode() 可以是负数,例如尝试更长的字符串。 ;)
  • @StevenSchlansker 对于非常大的值,这是一个问题,在这种情况下,您需要使用 long hashCode(甚至 BigDecimal)。通常,较小的值(小于一百万)
【解决方案2】:

您可以使用 String.hashCode()。

String a1 = "Hello World";
String a2 = new String(a1); // don't do this unless you have to have a different object.
System.out.println("Identity hashCode " + System.identityHashCode(a1) + " != " + System.identityHashCode(a2));
System.out.println("String.hashCode " + a1.hashCode() + " == " + a2.hashCode());

打印

Identity hashCode 551677275 != 1353056826
String.hashCode -862545276 == -862545276

在性能方面,hashCode() 比创建 String 本身要快得多。如果这还不够快,我会首先避免使用/创建字符串。 (你不太可能需要这样做)

每次运行程序时,身份哈希码都会发生变化。注意:hashCode() 可以为负数,因此您必须对此进行调整。

int hash = (text.hashCode() & 0x7FFFFFFF) % K + 1;

或者如果您不想丢弃最高位

int hash = (int) ((text.hashCode() & 0xFFFFFFFFL) % K + 1);

【讨论】:

    【解决方案3】:

    如果您需要一个安全的散列(一个不能轻易反转的散列),那么使用消息摘要:

    try {
        MessageDigest msgDigest = MessageDigest.getInstance("MD5");
        byte digest[] = msgDigest.digest(username.getBytes());
        int secureHash = 1 + new BigInteger(digest).mod(BigInteger.valueOf(k)).intValue();
    
        System.out.println("Secure hash " + secureHash);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    

    【讨论】:

      【解决方案4】:

      您可以继续使用 JDK 附带的 HashTable 或 HashMap。在两者之间进行选择,归根结底,

      • 对 Hashtable 的访问是在表上同步的,而 HashMap 不是。

      • HashMap 中的迭代器是故障安全的,而 哈希表不是。

      • HashMap 允许其中包含空值,而 Hashtable 不允许。

      HashMap 是新集合框架的一部分(从 JDK 1.2 开始)

      如果您有数百万个条目,请选择数据库。去NoSQL

      这里有类似的问题HashMap in Java, 100 Million entries

      【讨论】:

      • 我有数百万不同的用户
      猜你喜欢
      • 2018-11-01
      • 2021-09-14
      • 2013-05-31
      • 2012-02-19
      • 2018-05-20
      • 2013-04-17
      • 2018-10-13
      • 2012-09-26
      • 1970-01-01
      相关资源
      最近更新 更多