JDK之HashMap、HashSet分析

HashMap主要分析key、value的放入Map和取出Map操作以及他的遍历器。个人觉得在HashMap中有个很重要的内部类Entry,Map的put,get等重要方法都是依靠这个Entry的。先来分析下这个内部类Entry,Entry中有几个重要的变量key、value、next,不用说大家也会明白这几个变量的含义,当然也自然会有get和set方法了。当我们在遍历Map的时候,有一种方法就是获取这个内部类的对象entry,然后去这个entry中取值。现在就以这个为例,遍历一个Map。首先获取Map的entrySet集,然后获取迭代器:map.entrySet().iterator(),获取以后使用next方法拿到Entry,最后在Entry中拿到可以和Value,这种方式是首先拿到map的Entry对象,然后去拿key和value。不同于另外一种遍历方式:map.keySet().iterator(),他是先拿到key的集合,然后通过可以去取value。这两种方式最后都能遍历整个Map,但是实现的方式不一样,使用的内部类也不一样。遍历器都是在内部类中产生的,要想使用遍历器,必须使用内部类,其实在类中是不能直接调用Map中的内部类的,都是使用类中的方法,在方法中返回内部类的对象,从而去操纵内部类的方法,JDK源码中很多类都是这样操作的,这样很好影藏了内部类,但是这种做法的好处,我暂时还没有深刻体会,只觉得这样做使用了java的代理模式,也实现了java的多重继承(PS:希望有高手赐教这样使用内部类的好处和意义)。现在很细MAP中的重要方法:put。put就是将key和value放入到MAP当中,他先会拿到这个map的遍历这个map,拿到Entry,遍历map,如果有value等于当前的value,则将替换这个entry中的value,返回当前的entry,这样做是的map中key值对应的value永远只有一个,且是最新的,如果没有,则将当前这个key和value放入到entry中。在put的时候,map提供了putForNullKey方法,即,允许有key是null的,如果key是null的,则将key设置为null,跟普通的put一样,只是在比较是否存在为null的key时,不需要比较他的hash值,直接比较即可。当然,putForNullKey是私有的,只能通过put调用。map还提供了containsValuecontainsKey方法,其实现逻辑基本相同,都是变量Map,拿到Entry,然后比较key或者value。API中说Map中有两个影响其性能的参数:初始容量 和加载因子,这个不太了解,需要进一步分析。

HashSet其实底层的实现都是依赖于HashMap的,或者说他的方法实现是调用HashMap方法的。如HashSet的构造方法,就是new了一个HashMap,当向Set中add元素时,就是想Map中put值,只不过value设置为PRESENT,其中PRESENT是一个全局的object类型的对象,可以说Set其实就是一个Map,只是这个Map的value都是一样,是一个根类对象,只是key不同而已。由此可以想到为什么set中没有重复值,原因是因为Map中key是唯一的,若有重复的key,则替换的是value,此处value都一样,key肯定就唯一。当向set中添加相同元素时,都不需要异常处理,因为map的put实现方法决定了不会有异常的出现。set的其他方法不用过多分析,基本都是调用map中的方法。对于set的迭代器,他采用遍历map的方式为上面讲解的第二种map.keySet().iterator(),这样拿到map的迭代器,从而迭代set。要想很好的理解set,其实只需要理解map即可。

之所以HashMap和HashSet放在一起分析,原因很明了,其实这篇文章就是在分析HashMap。(PS:此处分析的主要是Map工作中常用的方法,可能还有很多有趣且有用的方法未分析,当用到时,需要好好的看下源码,理解这样做的理由)。

时间: 2024-08-06 21:35:03

JDK之HashMap、HashSet分析的相关文章

HashMap深度分析

java hashmap深度分析(转)   java.util.HashMap是很常见的类,前段时公司系统由于对HashMap使用不当,导致cpu百分之百,在并发环境下使用HashMap 而没有做同步,可能会引起死循环,关于这一点,sun的官方网站上已有阐述,这并非是bug. HashMap的数据结构          HashMap主要是用数组来存储数据的,我们都知道它会对key进行哈希运算,哈系运算会有重复的哈希值,对于哈希值的冲突,HashMap采用链表来解决的.在HashMap里有这样的

HashTable HashMap HashSet区别(java) [From 爱做饭的小莹子]

Hashtable: 1. key和value都不许有null值 2. 使用enumeration遍历 3. 同步的,每次只有一个线程能够访问 4. 在java中Hashtable是H大写,t小写,而HashMap是H大写,M大写 HashMap: 1. key和value可以有null值 2. 使用iterator遍历 3. 未同步的,多线程场合要手动同步HashMap HashSet 1. 底层调用HashMap 2. 不允许有重复值 常用Java操作: 1 Hashtable<Intege

HashTable HashMap HashSet区别(java)

Hashtable: 1. key和value都不许有null值 2. 使用enumeration遍历 3. 同步的,每次只有一个线程能够访问 4. 在java中Hashtable是H大写,t小写,而HashMap是H大写,M大写 HashMap: 1. key和value可以有null值 2. 使用iterator遍历 3. 未同步的,多线程场合要手动同步HashMap HashSet 1. 底层调用HashMap 2. 不允许有重复值 常用Java操作: 1         Hashtabl

JDK源码之HashMap 类分析

一 概述 HashMap实现 hashmap继承了AbstractMap,实现了Map接口和Cloneable接口,HashMap是基于哈希表(散列表),实现Map接口的双列集合 jdk8中底层数据结构已经改为二叉树,之前是链表 看hashmap之前,需要把Map,AbstractMap源码撸一遍,这里放我的博文链接: https://www.cnblogs.com/houzheng/p/12687883.html 涉及到的数据结构 二 源码分析 属性 静态内部类(Entry的实现) 三 总结

谈HashMap,HashSet,HashTable容易被我们忽视的问题

在平时开发中,HashMap,HashTable,HashSet 都是经常用到的键值映射数据结构,在这里我主要写一些平时我们使用这些数据结构中容易忽视的问题. HashMap HashMap的结构 HashMap 底层是一个Entry数组来支撑的,我觉得叫Entry链表数组支撑更为合适. 结构图: 每个entry数组里面的元素要么为null要么就是一个entry链表:而每个entry对象就是一个entry链表的节点也是一个键值对的抽象表示: HashMap的性能因素 HashMap主要影响其性能

ArrayList,Vector,HashMap,HashSet,HashTable之间的区别与联系

看上面的框架图,先抓住它的主干,即Collection和Map. 1 Collection是一个接口,是高度抽象出来的集合,它包含了集合的基本操作和属性. Collection包含了List和Set两大分支. (01) List是一个有序的队列,每一个元素都有它的索引.第一个元素的索引值是0. List的实现类有LinkedList, ArrayList, Vector, Stack. (02) Set是一个不允许有重复元素的集合. Set的实现类有HastSet和TreeSet.HashSet

Java基础系列之(三) - HashMap深度分析

这次主要是分析下HashMap的工作原理,为什么我会拿这个东西出来分析,原因很简单,以前我面试的时候,偶尔问起HashMap,99%的程序员都知道HashMap,基本都会用Hashmap,这其中不仅仅包括刚毕业的大学生,也包括已经工作5年,甚至是10年的程序员.HashMap涉及的知识远远不止put和get那么简单.本次的分析希望对于面试的人起码对于面试官的问题有所应付  一.先来回忆下我的面试过程  问:“你用过HashMap,你能跟我说说它吗?”  答:“当然用过,HashMap是一种<ke

HashMap/HashSet,hashCode,哈希表

HashMap实现了Map接口,该接口的作用主要是为客户提供三种方式的数据显示:只查看keys列表:只查看values列表,或以key-value形式成对查看.Map接口并没有定义数据要如何存储,也没有指定如何判定key是一样,因此并不是所有的Map实现都会与hashCode方法扯上关系,如TreeMap便是要求对象实现Comparator接口,通过其compare方法来比对两者是否一致,而非hashCode及equals.同理,如果我们自己实现Map接口,我们也可以直接使用数组进行数据存储使用

jdk TreeMap工作原理分析

TreeMap是jdk中基于红黑树的一种map实现.HashMap底层是使用链表法解决冲突的哈希表,LinkedHashMap继承自HashMap,内部同样也是使用链表法解决冲突的哈希表,但是额外添加了一个双向链表用于处理元素的插入顺序或访问访问. 既然TreeMap底层使用的是红黑树,首先先来简单了解一下红黑树的定义. 红黑树是一棵平衡二叉查找树,同时还需要满足以下5个规则: 1.每个节点只能是红色或者黑点 2.根节点是黑点 3.叶子节点(Nil节点,空节点)是黑色节点 4.如果一个节点是红色