在进行数据交换时,如果主键不是整型,需要对字符串,或联合主键拼接为字符串,进行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

最新文章

  1. Memcache所有方法及参数详解
  2. windows根据端口号找进程
  3. android 绘图之Path与Paint详解
  4. android布局 及 布局属性
  5. HW2.11
  6. 深入理解7816(3)-----关于T=0
  7. 为什么国内的网盘公司都在 TB 的级别上竞争,成本会不会太高?(还有好多其它回复)
  8. js 基础笔记三
  9. Jalor 5学习心得
  10. 20175204 张湲祯 2018-2019-2《Java程序设计》
  11. 使用Laya引擎开发微信小游戏(下)
  12. 【AGC005F】Many Easy Problems FFT 容斥原理
  13. 辽宁移动宽带体验及魔百盒M101s-2刷机
  14. Java 汇编代码
  15. 关于FlexSlider插件
  16. html5-fieldset和legend和keygen元素的用法
  17. 查看linux 内核版本信息
  18. 使用layui 和 jquery 问题小结
  19. php json_decode返回null
  20. 移植Max中的控制器到Unity - 前言

热门文章

  1. JPQ整合Querydsl入门篇
  2. P1828 香甜的黄油 Sweet Butter 最短路 寻找一个点使得所有点到它的距离之和最小
  3. 数字金字塔 动态规划(优化版) USACO 一维dp压缩版
  4. 3次方的期望dp
  5. hdu - 4965
  6. PTA - 拓扑排序
  7. mysql复习1
  8. 简述http协议及抓包分析
  9. Springboot + 持久层框架JOOQ
  10. 异数OS 2017 DPDK 峰会观后感