以前学习HahsMap都是粗略的了解一下,能够用就行了。这次对HahsMap的源代码看了几遍,对此有一定的理解,就我的理解我总结出如下几点。但在此之前,我们先说下HahsMap的结构,简单来说:HahsMap其实是一个数组和链表的结合体。
第一、首先对HahsMap的初始容量(也即DEFAULT_INITIAL_CAPACITY)来说个事,看下面的代码吧:
public class TestHashMap {
public static void main(String[] args) {
HashMap<Integer, Integer> hm1=new HashMap<Integer, Integer>();
HashMap<Integer, Integer> hm2=new HashMap<Integer, Integer>(1024<<7);
long time1=System.currentTimeMillis();
for(int i=0;i<100000;i++){
hm1.put(i, i);
}
long time2=System.currentTimeMillis();
long time3=System.currentTimeMillis();
for(int i=0;i<100000;i++){
hm2.put(i, i);
}
long time4=System.currentTimeMillis();
System.out.println("默认初始容量8所用时间为:"+(time2-time1));
System.out.println("定义初始容量131072所用时间为:"+(time4-time3));
}
}
程序运行的结果为:默认初始容量8所用时间为:94
定义初始容量131072所用时间为:47
可以看出,第二种方法所用时间基本上是前面的一半,这是为什么呢?其实,HashMap的rehash是一个非常消耗性能的操作,rehash的次数越多,所消耗的时间也就越长。当插入100000个元素时,使用初始容量rehash的次数会很多,而根据(100000)/0.75=133333(0.75是HashMap的默认装填因子),也即是说第二种方法只要rehash一次即可,所以消耗的时间会大大减少。
第二、HashMap的装填因子,按如上代码,我们稍做修改,把定义的hm1和hm2修改成如下:
HashMap<Integer, Integer> hm1=new HashMap<Integer, Integer>(1024<<7,1);
HashMap<Integer, Integer> hm2=new HashMap<Integer, Integer>(1024<<7);
在此运行,结果为:定义装填因子为1所用时间为:47
默认装填因子为0.75所用时间为:62
在这里,我们循环插入100000个数据,但根据HashMap中的hash()函数,基本呈均匀分布,这样,没有什么冲突,那当然是装满更好,插入的效率会提高。但并不是装填因子越大越好,因为我们并不知道插入的数据是不是接近于均匀分布,如果不是的话,那么冲突会很大,查询的效率就会降低,装填因子太小也不好,因为这样会很浪费空间。所以HashMap默认的装填因子取了个折中的数0.75。
小结下:装填因子衡量的是一个散列表的空间使用程度,装填因子越大表示散列表的装填程度越高,反之越小。我们知道对一个链表法的散列表来说,查询一个元素的平均时间为O(1+a),因此,如果装填因子越大,对空间的利用更充分,然而查询效率就会降低;如果装填因子过小,那么散列表的数据就过于稀疏,对空间造成严重的浪费。
总结下:如果你知道所要插入的数据的个数N,那么你可以定义HashMap的容量大小为:N/0.75,有因为HashMap的容量必须是2的幂次方,找一个接近的即可;如果你还知道其近似一个均匀分布的话,那么装填因子也可以自己定义,接近于1会更效率。
分享到:
相关推荐
深入理解hashmap、hash算法、理解加载因子、扩容以及get、put方法
对HashMap 源码逐行进行注释,带你深入理解HashMap原理,使面试不在困难,
深入理解HASHMAP底层原理,通过对源码进行解析分析HASHMAP执行过程,一篇文章帮助你深刻理解HASHMAP
主要介绍了java 中HashMap实现原理深入理解的相关资料,需要的朋友可以参考下
主要介绍了对HashMap原理的理解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
主要介绍了深入理解Java之HashMap源码剖析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
首先介绍一下什么是Map。在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value
主要介绍了深入理解Java中的HashMap的实现机制,同时也有助于理解Java中对于哈希函数的相关处理方式,需要的朋友可以参考下
1. HashMap的操作流程 1.1 HashMap的构造函数 首先我们来看一下HashMap的构造函数: /** * Constructs an empty {@code HashMap} with the specified initial * capacity and load factor. * * @param ...
在本套课程中,将会非常深入、非常详细、非常全面的解读HashMap以及源码底层设计的思想。从底层的数据结构到底层源码分析以及怎样使用提高HashMap集合的效率问题等进行分析。如果掌握本套课程,那么再看其他javase的...
是一本全面深入探讨 Rust 语言并发特性的指南。它从基础概念出发,逐步深入到高级话题,涵盖了线程、线程池、异步编程、同步原语等多个方面。书中不仅详细介绍了 Rust 标准库中的并发工具,还涉及了第三方库的使用,...
深入理解Java的反射机制 深入理解Java异常体系 谈谈NIO的理解 谈一谈对JUC的理解 ArrayList的底层原理 HashMap的底层原理 iava单例模式详解 JAVA的内存结构 java队列 Java基础思考之数据传递 JAVA内存泄漏详解 java...
深入理解Java的反射机制 深入理解Java异常体系 谈谈NIO的理解 谈一谈对JUC的理解 ArrayList的底层原理 HashMap的底层原理 iava单例模式详解 JAVA的内存结构 java队列 Java基础思考之数据传递 JAVA内存泄漏详解 java...
java源代码原理,深入理解HashMap原理、高可用redis集群架构、zookeeper分布式、海量数据缓存、springAOP底层源码分析等
4、深入理解Java的反射机制 5、深入理解Java异常体系 6、谈谈NIO的理解 7、谈一谈对JUC的理解 8、ArrayList的底层原理 9、HashMap的底层原理 10、Java单例模式详解 11、JAVA的内存结构 12、java队列 13、Java基础...
ava基础 基础知识 ...Java集合详解5:深入理解LinkedHashMap和LRU缓存 Java集合详解6:TreeMap和红黑树 Java集合详解7:HashSet,TreeSet与LinkedHashSet Java集合详解8:Java集合类细节精讲 JavaWeb
从无到有手写HashMap,深入理解JDK底层HashMap的实现原理,自定义自己的数据结构。
本文将对Java常见面试题进行总结和解析,旨在为准备面试的Java开发者提供全面而深入的学习参考。...建议读者结合实际代码示例和项目经验,深入理解和掌握这些知识点,并不断练习和总结,以提高自己的面试成