Java SE HashMap的底层实现
1.hash散列算法
由于hashmap在存储过程中是数组加链表的存储过程,所以定义数组长度为16(建议是2的n次幂的长度),之后进行每个数组的地址都指向一个链表进行存储
hash表算法可对数组长度length取余,如果length是2的n次幂,则可对length-1取位运算&
例如,任意长度8是2的3次幂,随机的int值对8取余,和对7进行&运算得到的结果是一样的
int a=;
System.out.println(a%);
System.out.println(a&);
在jdk 7之前的源码中,则对hash凑得进行了2次散列处理,为了使散列更均匀
在jdk 8往后,数组长度大于8时,链表转换为红黑树,大大提高了查找速率
2.手工实现hashMap
取数据
1.首先通过key计算hashcode来得到数组的存储,再通过next便利链表进行查找比较,直到返回true的节点对象为止
2.Java中有规定,两个内容相同的(调用equals方法值为true的)对象必须有想等的hashcode,如果两个对象内容相等,而hashcode的值不一样,则会产生悖论
扩容问题
1.jdk7之前
hashMap的位桶数组,初始大小为16,实际使用时,大小可变,如果位桶数组中元素个数达到(0.75*数组length),就重新调整数组为2倍大小,扩容是个耗时的过程,相当于重新定义数组和链表,进行复制操作
2.jdk8之后
位桶数组初始大小为16,当链表长度大于8时,将链表中各个元素拷贝到红黑树上,大大提高了查找效率
3.源代码
package com.littlepage.HashMap;
/**
* 用于LittlePagesHashMap的Node
* @author LittlePage
*/
public class Node<K,V> {
private int hash;
private K key;
private V value;
private Node<K,V> next; public Node(K key, V value) {
super();
this.key = key;
this.value = value;
} public int getHash() {
return hash;
} public void setHash(int hash) {
this.hash = hash;
} public K getKey() {
return key;
} public void setKey(K key) {
this.key = key;
} public V getValue() {
return value;
} public void setValue(V value) {
this.value = value;
} public Node<K, V> getNext() {
return next;
} public void setNext(Node<K, V> next) {
this.next = next;
} @Override
public String toString() {
return "(" + key + "," + value + ")";
} }
package com.littlepage.HashMap; public class LittlePagesHashMap<K,V> { Object[] table=new Node[]; //位桶数组 int size;//存放键值对个数 public LittlePagesHashMap(){
table=new Node[];
} public void put(K key,V value){
//定义了新的节点对象
Node<K,V> newNode=new Node<>(key,value);
newNode.setHash(myHash(key.hashCode(), table.length)); @SuppressWarnings("unchecked")
Node<K,V> temp=(Node<K, V>) table[newNode.getHash()];
if(temp==null){
table[newNode.getHash()]=newNode;
}else{
while(temp.getNext()!=null){
if(temp.getKey().equals(newNode.getKey())){
temp.setValue(newNode.getValue());
size++;
return;
}
temp=temp.getNext();
}
temp.setNext(newNode);
}
size++;
} public int myHash(int hashcode,int length){
return hashcode&(length-);
} @Override
public String toString(){
StringBuilder sb=new StringBuilder();
sb.append("[");
for(int i=;i<table.length;i++){
if(table[i]==null) continue;
else{
@SuppressWarnings("unchecked")
Node<K,V> temp=(Node<K, V>) table[i];
sb.append(temp);
while((temp=temp.getNext())!=null){
sb.append(","+temp);
}
sb.append("]");
}
}
return sb.toString();
}
}
package com.littlepage.HashMap; public class Test {
public static void main(String[] args) {
LittlePagesHashMap<String, String> a=new LittlePagesHashMap<>();
a.put("a", "gg");
a.put("", "pp");
System.out.println(a);
}
}
Java SE HashMap的底层实现的更多相关文章
- 再学Java 之 HashMap的底层实现
今天参加欢聚时代的面试,我说我自己依靠自己的理解重新实现过HashMap.描述我自己的实现思想后,面试官问“hashmap”底层如果用数组不是效率比较低吗,不是更应该用红黑树吗?我一下子就蒙了.用数组 ...
- Java SE LinkedList的底层实现
关于实现链表的底层原理 链表便于增删,不便于查询 package com.littlepage.linkedList; /** * 基于底层实现LinkedList * @author Littlep ...
- java.util.HashMap的简单介绍
1. java.util.HashMap的底层实现是数组+链表. 2. 简介put(key, value)方法的执行过程: 1)通过key值,使用散列算法计算出来一个hash值,用来确定该元素需要存储 ...
- 深入解析Java对象的hashCode和hashCode在HashMap的底层数据结构的应用
转自:http://kakajw.iteye.com/blog/935226 一.java对象的比较 等号(==): 对比对象实例的内存地址(也即对象实例的ID),来判断是否是同一对象实例:又可以说是 ...
- [转]java 的HashMap底层数据结构
java 的HashMap底层数据结构 HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在.在HashMap中,key-v ...
- java 的HashMap底层数据结构
HashMap也是我们使用非常多的Collection,它是基于哈希表的 Map 接口的实现,以key-value的形式存在.在HashMap中,key-value总是会当做一个整体来处理,系统会根据 ...
- Java中HashMap底层实现原理(JDK1.8)源码分析
这几天学习了HashMap的底层实现,但是发现好几个版本的,代码不一,而且看了Android包的HashMap和JDK中的HashMap的也不是一样,原来他们没有指定JDK版本,很多文章都是旧版本JD ...
- Java中HashMap底层原理源码分析
在介绍HashMap的同时,我会把它和HashTable以及ConcurrentHashMap的区别也说一下,不过本文主要是介绍HashMap,其实它们的原理差不多,都是数组加链表的形式存储数据,另外 ...
- Java SE 6 新特性: 对脚本语言的支持
2006 年底,Sun 公司发布了 Java Standard Edition 6(Java SE 6)的最终正式版,代号 Mustang(野马).跟 Tiger(Java SE 5)相比,Musta ...
随机推荐
- springboot打包部署到tomcat
一. springboot打成war包: 1. 首先查看是否为war 2. File----->ProjectStruture,选择Artifacts,中部点击“+”号 3. 按图中标记进行选择 ...
- JVM虚拟机详解
1. 什么是JVM? JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来 ...
- django中模型详解-字段类型与约束条件
这片博文来详细说明django模型的使用,涉及到django模型的创建,字段介绍,以及django模型的crud操作,以及一对一等操作. 在使用模型之前,我们首先设置数据库选项,django的默认数据 ...
- P2473 [SCOI2008]奖励关(期望)
P2473 [SCOI2008]奖励关 $n<=15$,显然的状压 设$f[i][w]$表示前$i$轮,状态$w$的最大期望 蓝后我们发现一个问题:$f[i][w]$可能是非法的 于是我们从$f ...
- Java操作文件Util
package io.guangsoft.utils; import java.io.File; import java.io.FileInputStream; import java.io.File ...
- android官方开发教程解释(一)
最近准备系统学一下android开发,这里不会照搬原文,只会针对教程中一些难以理解的部分进行解释,我只是个菜鸟. 在教程第一章——入门基础里面,讲解android主题的那个小节,大概会有以下的代码: ...
- win-Linux文件脚本迁移过程中的问题 syntax error: unexpected end of file
问题: 在win下写好的shell脚本,放到Linux上测试sh -n报错如下 ORA_check.sh: line 251: syntax error: unexpected end of fil ...
- opencv学习之路(11)、图像几何变换
一.图像缩放 #include<opencv2/opencv.hpp> using namespace cv; void main(){ Mat src=imread("E:// ...
- 支持图片上传预览的 uploadPreview.js 插件
原文链接:http://www.lanrenzhijia.com/others/3148.html
- Centos7.03搭建JDK、Tomcat、MySql环境
本人linux服务器配置是:centos_7_03_64_20G_xdragon_20171025.vhd 公网IP:106.14.14.224 内存:2GB SecureCRT8.0:https:/ ...