概述
最近刚好有空来学习哈希表的相关知识,预计分成三个阶段去了解哈希表及其实现,目前这篇是初级阶段。
初级阶段:了解java当中hashCode的生成,及8种基本数据包装类型的hashCode码的各自生成,及源码解析。
中级阶段:了解哈希表的数据结构及实现,LinkedHashMap的原理。
高级阶段:了解哈希表的优化,Hash碰撞攻击,分段锁机制。
测试代码
package com.algorithm;
import java.util.logging.Logger;
/**
* 哈希表(初级阶段-了解)
*
* @date 2018年1月23日 下午10:19:00
* @author [email protected]
*
*/
public class HashTable {
private static Logger logger = Logger.getAnonymousLogger();
public static void main(String[] args) {
//8中基本数据类型
//int
Integer param1 = new Integer(10);
//short
Short param2 = new Short((short) 10);
//long
Long param3 = new Long(10);
//float
Float param4 = new Float(10.0);
//double
Double param5 = new Double(10.0);
//boolean
Boolean param6 = new Boolean(true);
//byte(-128到127)
Byte param7 = new Byte((byte) 128);
//char(存储单个字符)
Character param8 = new Character('a');
logger.info(param1.hashCode() + "");//int
logger.info(param2.hashCode() + "");//short
logger.info(param3.hashCode() + "");//long
logger.info(param4.hashCode() + "");//float
logger.info(param5.hashCode() + "");//double
logger.info(param6.hashCode() + "");//boolean
logger.info(param7.hashCode() + "");//byte(-128到127)
logger.info(param8.hashCode() + "");//char(存储单个字符)
}
}
控制台效果
一月 23, 2018 10:19:36 下午 com.algorithm.HashTable main
信息: 10
一月 23, 2018 10:19:37 下午 com.algorithm.HashTable main
信息: 10
一月 23, 2018 10:19:37 下午 com.algorithm.HashTable main
信息: 10
一月 23, 2018 10:19:37 下午 com.algorithm.HashTable main
信息: 1092616192
一月 23, 2018 10:19:37 下午 com.algorithm.HashTable main
信息: 1076101120
一月 23, 2018 10:19:37 下午 com.algorithm.HashTable main
信息: 1231
一月 23, 2018 10:19:37 下午 com.algorithm.HashTable main
信息: -128
一月 23, 2018 10:19:37 下午 com.algorithm.HashTable main
信息: 97
- 这里采用的是jdk自带的logger类。
Object的hashCode方法实现
public native int hashCode();
- 细心的开发者会发现,java并没有提供Object方法的hashCode方法的实现,而是定义了一个没有实现的native方法,它其实调用的是c语言底层的方法库的实现方法,也就是说c语言帮java做了这件事情,我的理解是这个地方体现了java的跨平台性。
- 这里附带c的源码实现,我就不做解读了。
- https://www.zhihu.com/question/29976202
- http://www.bkjia.com/ASPjc/919437.html
Integer的hashCode方法实现
public int hashCode() {
return value;
}
Short的hashCode方法实现
public int hashCode() {
return (int)value;
}
- 这个地方采用了强制转换
Long的hashCode方法实现
public int hashCode() {
return (int)(value ^ (value >>> 32));
}
- 这个地方采用了位运算符。
Float的hashCode方法实现
public int hashCode() {
return floatToIntBits(value);
}
public static int floatToIntBits(float value) {
int result = floatToRawIntBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & FloatConsts.EXP_BIT_MASK) ==
FloatConsts.EXP_BIT_MASK) &&
(result & FloatConsts.SIGNIF_BIT_MASK) != 0)
result = 0x7fc00000;
return result;
}
- 这里内部实现调用的是Float的静态方法floatToIntBits来获取hashCode值
Double的hashCode方法实现
public int hashCode() {
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
public static long doubleToLongBits(double value) {
long result = doubleToRawLongBits(value);
// Check for NaN based on values of bit fields, maximum
// exponent and nonzero significand.
if ( ((result & DoubleConsts.EXP_BIT_MASK) ==
DoubleConsts.EXP_BIT_MASK) &&
(result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)
result = 0x7ff8000000000000L;
return result;
}
- 这里调用的是Double内部的doubleToLongBits静态方法
- 返回hashCode值时采用了位运算符。
- 在doubleToLongBits内部方法实现时,调用了c语言的doubleToRawLongBits实现方法,java本身并没有提供此方法的实现
- 在进行运算时,采用16进制数。
Boolean的hashCode方法实现
public int hashCode() {
return value ? 1231 : 1237;
}
- 这个估计是java中最简单的返回hashCode的方式,哈哈,直接固定好,返回给你,true返回1231,false返回1237,还有这种蛇皮操作。
Byte的hashCode方法实现
public int hashCode() {
return (int)value;
}
Character的hashCode方法实现
public int hashCode() {
return (int)value;
}
学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:543120397 我们一起学Java!