HashMap和HashSet原理及底层实现
HashMap底层用哈希算法实现,下面看一下哈希算表的整体概括:
当map.put(“key”,”values”);的时候,底层是这样的:
static final Entry<?,?>[] EMPTY_TABLE = {};
transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;
/**
* The number of key-value mappings contained in this map.
*/
transient int size;
int threshold; // 临界值 它等于HashMap的容量乘以负载因子
final float loadFactor;// 负载因子
public V put(K key, V value) {// 如果table为空,则使其不为空if (table == EMPTY_TABLE) {inflateTable(threshold);}// 如果key为null,调用putForNullKey处理if (key == null)return putForNullKey(value);int hash = hash(key);// 搜索指定hash值对应的索引int i = indexFor(hash, table.length);for (Entry<K,V> e = table[i]; e != null; e = e.next) {Object k;// 如果hash值相同,并且equals比较返回true,则覆盖,然后返回被覆盖的if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}// 如果i索引处的entry为null,表明此处还没有entrymodCount++;addEntry(hash, key, value, i);return null;
}
// 添加entry
void addEntry(int hash, K key, V value, int bucketIndex) {if ((size >= threshold) && (null != table[bucketIndex])) {resize(2 * table.length);//原来长度的2倍hash = (null != key) ? hash(key) : 0;bucketIndex = indexFor(hash, table.length);}createEntry(hash, key, value, bucketIndex);
}
void createEntry(int hash, K key, V value, int bucketIndex) {Entry<K,V> e = table[bucketIndex];// 头插法建立链table[bucketIndex] = new Entry<>(hash, key, value, e);size++;}
void resize(int newCapacity) {Entry[] oldTable = table;//先记录下来tableint oldCapacity = oldTable.length;if (oldCapacity == MAXIMUM_CAPACITY) {threshold = Integer.MAX_VALUE; //static final int MAXIMUM_CAPACITY = 1 << 30;return;}Entry[] newTable = new Entry[newCapacity];//这个是原来长度的2倍transfer(newTable, initHashSeedAsNeeded(newCapacity));table = newTable;threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);}/*** Transfers all entries from current table to newTable.*/void transfer(Entry[] newTable, boolean rehash) {// rehash 是否重新hashint newCapacity = newTable.length;for (Entry<K,V> e : table) {while(null != e) {Entry<K,V> next = e.next;if (rehash) {e.hash = null == e.key ? 0 : hash(e.key);}int i = indexFor(e.hash, newCapacity);e.next = newTable[i];newTable[i] = e;e = next;}}}/*** Initialize the hashing mask value. We defer(延迟) initialization until we* really need it.*/final boolean initHashSeedAsNeeded(int capacity) {boolean currentAltHashing = hashSeed != 0;boolean useAltHashing = sun.misc.VM.isBooted() &&(capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD);boolean switching = currentAltHashing ^ useAltHashing;if (switching) {hashSeed = useAltHashing? sun.misc.Hashing.randomHashSeed(this): 0;}return switching;}
// 内部类 entry
static class Entry<K,V> implements Map.Entry<K,V> {final K key;V value;Entry<K,V> next;// 指向下一个entryint hash;/*** Creates new entry.*/Entry(int h, K k, V v, Entry<K,V> n) {value = v;next = n;key = k;hash = h;}
说明:
对于HashMap及其子类而言,它们采用Hash算法来决定集合中元素的存储位置。当系统开始初始化HashMap时,系统会创建一个长度为capacity的Entry数组,这个数组里可以存储元素的位置被称为“桶(bucket)”,每个bucket都有其指定索引,系统可以根据其索引快速访问该bucket里存储的元素。当每个bucket只存储一个元素时,HashMap性能最好。当解决冲突而产生的链越长,性能越差。
装填因子load factor,默认值是0.75,这个是空间和时间的折衷,增大装填因子,可以减小Hash表所占用的空间,但会增加查找时间,减小装填因子,会提高数据查询性能,但会增加Hash表所占用的内存空间。
在new 一个hashMap的时候,可以适当的传入要建立的大小,传入的应该是2的n次幂。
HashSet的底层实现
HashSet底层是通过HashMap实现的,看如下的构造函数,构造HashSet的时候底层就构造了一个HashMap
public HashSet() {map = new HashMap<>();
}
private static final Object PRESENT = new Object();
public boolean add(E e) {return map.put(e, PRESENT)==null;
}
add的时候调用map的put方法,value始终是PRESENT。
The general contract of hashCode is:
· Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
· If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
· It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
相关文章:

Study on Android【三】--Intent消息传递
在前面写Android的ContentProvider时候,可以看到那是基于观察者模式的一个消息传递方法。每一个Cursor、ContentResolver做为一个小的注册中心,相关观察者可以在这个中心注册,更新消息由注册中心分发给各个观察者。而在MFC或Winform中&#x…
Matlab与数据结构 -- 对矩阵的排序
本图文介绍了Matlab怎样实现对矩阵的排序。

Java_中快速获取系统时间
直接调用System的currentTimeMillis()即可! long start System.currentTimeMillis(); System.out.println("Start time : "start);
servlet必知细节(一)
servlet必知细节(一) 今天复习了一下servlet,有过一些编程经验后,与最初学习servlet相比,对servlet理解的角度不同了,最初只是学习了如何写一个servlet,api怎么用,现在从更深处了解了…

办公室“暧昧”的几种结局。
暧昧结局一:以消散结尾 外贸公司职员小雨 p: [( I J( n, i/ L( L 那是我刚来这家公司的时候,参加面试时我就关注到其中一个面试我的男人长得不错,言谈举止也都很儒雅,所以第一面就留下了深刻印象。等到我被录取正式上班后…
Matlab与机器学习-- 数据的归一化
本文介绍了Matlab对数据归一化的处理函数mapminmax。

ASP.NET中的母版页
ASP.NET中的母版页 添加一个"母版页",使用<asp:ContentPlaceHolder>挖坑,新建的母版页已经自动设置了两个ContentPlaceHolder创建使用母版页的具体页面,WebSite是新建"Web窗体"的时候勾选"选择模板页",WebApplication是新建"Web内容窗…
servlet必知细节(二)--servlet执行过程
servlet必知细节(二)--servlet执行过程 我们知道,servlet没有main函数,那么,servlet是怎么调用的呢?实际上,servlet 是由tomcat调用的,tomcat调用servlet程序执行。由调用栈可以看到,当一个请求…

workerman源码分析之启动过程
2019独角兽企业重金招聘Python工程师标准>>> http://www.cnblogs.com/CpNice/p/4714182.html 转载于:https://my.oschina.net/yonghan/blog/898076

MD5加密方法
/**//// <summary>/// 16位MD5加密方法/// </summary>/// <param name"str">原文</param>/// <returns>密文</returns>publicstaticstringgetMd5(stringstr){ MD5CryptoServiceProvider md5 new MD5CryptoServiceProvider()…
如何教计算机认识手写数字(上)
本图文介绍了一种简单的教会计算机识别手写数字的方法。

servlet必知细节(三)-- DefaultServlet
servlet必知细节(三)-- DefaultServlet 缺省servlet:org.apache.catalina.servlets.DefaultServlet,作用是处理其他servlet处理不到的请求 我们知道,在我们工程的web.xml中,会配置servlet映射,…

第五篇:Visual Studio 2008 Web开发使用的新特性
第五篇:Visual Studio 2008 Web开发使用的新特性 本篇翻译自MSDN。 .NET Framwork 3.5与Visual Studio 2008 包含很多新特性。AJAX的Web开发人员支持与综合查询语言(LINQ)是其中最重要的更新。此外还包含一些新的服务器端控件以及客户端对象库…

Jenkins使用Publish Over FTP Plugin插件上传FTP详解
一、安装插件【Publish Over FTP】 二、在【系统管理】->【系统设置】->【Publish over FTP】->点击【增加】按钮,增加一个要连接的FTP: FTP Server Name:FTP名字 Hostname:主机IP或者域名 Username:ftp登陆用…
Matlab与数据结构 -- 求向量或矩阵的最大值
本图文介绍了Matlab中求向量或矩阵最大值的方法。
web应用的绝对路径和相对路径
经常写web工程,就会涉及很多路径问题,今天复习下绝对路径和相对路径,以提醒自己下次不要以为路径问题头疼。 1.绝对路径和相对路径 相对路径:helloworld ./helloworld ../helloworld 这样的都是相对路径绝对路径&…

IE7外觀優化
众所周知,在Windows Vista的默认设置中,传统的文件菜单消失了,大部分过去通过菜单执行的任务如今由工具栏提供,或者在相应选择项的右键属性里。尽管这种改变使页面布局更简洁,但似乎许多用户并不认可或者至少说并不习惯…

使用GPUImageView录制视频保存后出现绿边
2019独角兽企业重金招聘Python工程师标准>>> 最近在使用GPUimageView做视频录制功能,录完后发现保存的视频右边有绿边,觉得好奇怪呀,为什么会这样呢?于是上网找资料,发现了这么一个说法:GPU和视…
Matlab与数据结构 -- 搜索向量或矩阵中非零元素的位置
本图文介绍了Matlab中搜索向量或矩阵中非零元素位置的方法。
jdk7新特性学习笔记
jdk7新特性学习笔记 从网络down了视频看,记录下学过的东西。1.二进制字面量 JDK7开始,可以用二进制来表示整数(byte,short,int和long),语法:在二进制数值前面加 0b或者0B例如:int x 0b11112.数字字面量可以…

2008开年大礼:《Application = Code + Markup》中文版面世
Charles Petzold的又一部经典力作《Application Code Markup》中文版终于要面世了。成为2008 开年大礼。相信有很多对WPF有兴趣,但又苦于没有经典书籍来支撑的朋友都一直在期待着这本书的中文版上市,博文视点让这一期待成为现实。 与大家一样都很兴奋。…

近一个月的学习总结(4.8—5.12)
Java-se基础知识的学习已经告一段落,对自己这一个月的知识体系做一个大致的总结: 1.Java语言基础(基础完成) 2.面向对象基础(封装、继承、多态)(基础完成) 3.抽象类、接口࿰…
利用BP神经网络教计算机识别语音特征信号(代码部分SS)
本图文已经更新,详细地址如下: http://blog.csdn.net/lsgo_myp/article/details/54094884

springmvc配置DispatcherServlet拦截url注意事项
<!-- 前端控制器 --><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 加载springmvc配置 --><init-param><param-name>contex…

sql server面试题
本面试题由2344095 (有心人)整理, 由ashzs((可以包含中文字符)) 解答,感谢二位!1.磁盘柜上有14块73G的磁盘, 数据库为200G 大小包括日志文件,如何设置磁盘(要说明这14磁盘是怎么用的)?2.有两服务器群集,分别…
利用BP神经网络教计算机识别语音特征信号(代码部分SSR)
本图文已经更新,详细地址如下: http://blog.csdn.net/lsgo_myp/article/details/54094884

JDBC使用步骤
JDBC编程步骤: 一、注冊载入JDBC驱动程序; 注冊载入驱动driver。也就是强制类载入:其注冊载入JDBC驱动有三种方法: 方法一:Class.forName(DriverName); 当中DriverNameDriver包名。Driver类名;…

在mac下搭建java开发环境
刚刚从windows系统转到使用mac系统,感觉不是特别熟悉,需要一定的适应时间。下面简单介绍一下mac下搭建基本的java开发环境。 1.安装jdk 安装jdk1.7后,发现不需要进行环境变量配置,直接在terminal中就能使用java和javac命令了。j…

IT项目管理入门知识
转载于:https://www.cnblogs.com/sophia194910/p/6854462.html
什么是BP神经网络?
BP人工神经网络原理