java String hashCode遇到的坑
在进行数据交换时,如果主键不是整型,需要对字符串,或联合主键拼接为字符串,进行hash,再进行取模分片,使用的是String自带的hashCode()方法,本来是件很方便的事,但是有些字符串取hashCode竟然是负数,使得分片为负数,找不到对应的分片,我们先看一下String 生成hashCode的代码:
/**
* Returns a hash code for this string. The hash code for a
* {@code String} object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using {@code int} arithmetic, where {@code s[i]} is the
* <i>i</i>th character of the string, {@code n} is the length of
* the string, and {@code ^} indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
主要是根据字符串中字符的ascii码值来计算的,即 31 * hash + 字符的ASCII码值,int型的值取值范围为Integer.MIN_VALUE(-2147483648)~Integer.MAX_VALUE(2147483647),所以如果字符串比较长,计算的数值就可能超出Integer.MAX_VALUE,造成数值溢出,值变成负数
几种比较极端的字符串hashCode值:
String hashStr0 = "35953305172933/";
System.out.println(hashStr0.hashCode()); // 2147483647 Integer.MAX_VALUE
System.out.println(Math.abs(hashStr0.hashCode())); // 2147483647 Integer.MAX_VALUE
System.out.println("-------------------");
String hashStr = "359533051729330";
System.out.println(hashStr.hashCode()); // -2147483648 Integer.MIN_VALUE
System.out.println(Math.abs(hashStr.hashCode())); // -2147483648 Integer.MIN_VALUE
System.out.println("-------------------");
String hashStr2 = "56800004874";
System.out.println(hashStr2.hashCode()); // -2082984168
System.out.println(Math.abs(hashStr2.hashCode())); //
System.out.println("-------------------");
String hashStr3 = "";
System.out.println(hashStr3.hashCode()); //
System.out.println(Math.abs(hashStr3.hashCode())); //
System.out.println("-------------------");
对于字符串“359533051729330”的hashCode为Integer.MIN_VALUE,我们使用取绝对值还是超出Integer.MAX_VALUE,还是Integer.MIN_VALUE,所以针对这种极端情况是不可用的
要想利用hashCode为非负数,可以Integer.MAX_VALUE和与操作,这样最大正整数的符号位为0,与任何数与操作都是0,即是正数
int hash = str.hashCode() & Integer.MAX_VALUE;
2147483647 Integer.MAX_VALUE
java String hashCode遇到的坑的更多相关文章
- 面试话痨(二)C:JAVA String,别以为你穿个马甲我就不认识你了
面试话痨系列是从技术广度的角度去回答面试官提的问题,适合萌新观看! 面试官,别再问我火箭怎么造了,我知道螺丝的四种拧法,你想听吗? String相关的题目,是面试中经常考察的点,当面试中遇到了St ...
- Java总结篇系列:Java String
String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. 1 ...
- java集合-hashCode
hashCode 的作用 在 Java 集合中有两类,一类是 List,一类是 Set 他们之间的区别就在于 List 集合中的元素师有序的,且可以重复,而 Set 集合中元素是无序不可重复的.对于 ...
- Java中hashCode的作用
转 http://blog.csdn.net/fenglibing/article/details/8905007 Java中hashCode的作用 2013-05-09 13:54 64351人阅 ...
- Java String类详解
Java String类详解 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生. 类结构: public final ...
- java 覆盖hashCode()深入探讨 代码演示样例
java 翻盖hashCode()深入探讨 代码演示样例 package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要 ...
- Java String 的equals, == , hascode的区别
1.equals 和 == ==在java中是比较引用的,即在内存中的地址.而String的equals()是比较字符串的内容 http://blog.csdn.net/barryhappy/arti ...
- java 中hashcode和equals 总结
一.概述 在Java中hashCode的实现总是伴随着equals,他们是紧密配合的,你要是自己设计了其中一个,就要设计另外一个.当然在多数情况下,这两个方法是不用我们考虑的,直 ...
- Java String类具体解释
Java String类具体解释 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,非常多时候,我们对它既熟悉又陌生. 类结构: public fin ...
随机推荐
- 序列化之二(将"\/Date(942289871000)\/"格式的时间替换成"yyyy-MM-dd HH:mm:ss"格式)
序列化就是一种用来处理对象流的机制.所谓对象流也就是将对象的内容进行流化,流的概念这里不用多说(就是I/O).我们可以对流化后的对象进行读写 操作,也可将流化后的对象传输于网络之间(注:要想将对象传输 ...
- matplotlib 条形图
一.特点 离散数据,数据之间没有直接的关系 二.分类 1.垂直条形图 bar(x, height, width=0.8) # x 为x轴 # height 为y轴 # width 为 条形图的宽度 例 ...
- 编程基础系列--之--浅谈List、Set、Map和泛型(一)——单列集合
之前在学习Java时对于泛型,集合的理解一直模模糊糊,随着时间的推移,对泛型和集合有了一些浅显的认知,打算写出来巩固一下,也希望各位大佬能指出理解不当之处,万分感谢!!! 在Java语言中,集合分为两 ...
- error while loading shared libraries: libevent-2.1.so.6 的解决办法
执行 memcached 启动命令时,报错,提示:error while loading shared libraries: libevent-2.1.so.6: cannot open shared ...
- Xen+OpenQRM快速部署
一.选择系统平台 a) Ubuntu-11.10-server-amd64 二.Xen安装 a) Xen安装 # apt-get -y install xen-hypervisor-4.1-a ...
- 为什么RChain区块链上一定要有REV?
RChain区块链网络上一定要有REV吗?它的作用是什么?在这篇文章里,RChain创始人Mr. Greg Meredith做了详细解读,便于业界和社区对RChain网络有更深入的认识. 作者:Gre ...
- 【故障公告】SQL语句执行超时引发网站首页访问故障
非常抱歉,今天早上 6:37~8:15 期间,由于获取网站首页博文列表的 SQL 语句出现突发的查询超时问题,造成访问网站首页时出现 500 错误,由此给您带来麻烦,请您谅解. 故障的情况是这样的. ...
- 深浅拷贝 集合(定义,方法) 函数(定义,参数,return,作用域) 初识
深浅拷贝 在python中浅拷贝 a=[1,2,3,4,]b=a.copy()b[0]='3333'print(a) #[1, 2, 3, 4] 浅拷贝一层并不会对a造成变化print(b) #[33 ...
- C++快读模板
C++的快速读入模板 inline int read() { ; char ch = getchar(); ') { if (ch == '-') flag = true; ch = getchar( ...
- Java异常 | Error:java: Compilation failed: internal java compiler error
背景 今天网上下载了一个项目,编辑运行报如下异常: Error:java: Compilation failed: internal java compiler error 经过往经验,读项目的编译环 ...