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 ...
随机推荐
- Django框架---- 自定义分页组件
分页的实现与使用 class Pagination(object): """ 自定义分页 """ def __init__(self,cur ...
- 用Intellij IDEA建mybatis案例
用IDEA建mybatis案例 环境准备: 首先,建库建表(最好用navicat或sqlpro直接导) 然后打开IDEA, 1. java--->javaEE---> java app-- ...
- Yii1使用Gii生成模块实现CURD
Yii里Gii的强大就不用说了,可以快速生成模块的Model.Controller来开发.要使用Gii,首先你需要创建好操作的数据表. 第一步:创建数据表 CREATE TABLE `t_knowle ...
- 同级div设置display:inline-block,父级div强制不换行
同级div设置display:inline-block,父级div强制不换行 <html> <head></head> <body> <div i ...
- jackson/fastjson、mybatis、mysql date/datatime/timestamp、java Date/Timestamp关系详解
jackson/fastjson序列化/反序列化: 默认情况下,jackson/fastjson将java Date/Timestamp类型序列化为时间戳,也就是1970年1月1日0点以来的毫秒数.如 ...
- 【题解】Luogu P2319 [HNOI2006]超级英雄
原题传送门 这道题就是一个很简单的二分图匹配 二分图匹配详解 一开始想的是2-sat和网络流,根本没想匈牙利和HK 这道题只要注意一点:当一个点匹配不成功之后就直接退出 剩下的就写个二分图最大匹配就行 ...
- git 随笔
还有一些git的指令没有用过,记录在这里. 1. 设置远程branch的指令 There is no tracking information for the current branch.Pleas ...
- 免费CDN公共库——网站提速 静态资源库
原文链接:https://blog.geekzhao.me/cdnjs.html 新浪SAE公共资源 推荐指数★★★ 支持https http://lib.sinaapp.com/js/jquery/ ...
- Activity之Serializable
Student.java package cn.itcast.wh08.multiactivity.domain; import java.io.Serializable; public class ...
- JUnit Parametrized Tests
Junit allows us to create parametrized tests. Parametrized test class has to be annotated with the @ ...