JDK1.7 hashMap的简单实现
来源:互联网 发布:js 寻找字符串 编辑:程序博客网 时间:2024/06/03 23:44
HashMap是我们在日常的开发中最长见的类之一,对于HashMap的使用在这里就不用过多的解释了。我们来看看HashMap的简单的实现原理。
首先在jdk1.7之前的版本中,HashMap的实现的都是依靠的,(数组 + 链表)的数据结构。在jdk1.8中采用的是(数组 + 红黑树)的数据结构。
对于HashMap的理解,首先我们可以简单的自己写一个HashMap的实现来加深理解,那么就先不考虑jdk1.8,用(数组 + 链表)的形式来简单的实现。
1.定义一个ICustomMap接口方法有put(), get()方法,并且定义一个Entry内部接口
2.一定一个ICustomHashMap的类实现ICustomMap,实现put()和get()方法
uml图如下:
具体的代码如下:
public interface ICustomMap<K, V> { K put(K key, V value); V get(K key); interface Entry<K, V> { K getKey(); V getValue(); }}public class ICustomHashMap<K, V> implements ICustomMap { @Override public Object put(Object key, Object value) { return null; } @Override public Object get(Object key) { return null; }}
那么就开始实现put()方法。
实现的大致思路是:
对(数组 + 链表)的结构可以这样理解。一堆数据我们按照某个规律分为几个桶,就是分为几个数组,那么分到一个通的,我们可以称之为hash冲突,如何解决hash冲突呢,hashmap的操作是把产生hash冲突的数据按照链表的形式存储起来(有点像ArrayList + linkList的结合)。
那么就开始实现put的方法:
@Override public Object put(Object key, Object value) { int hash = key.hashCode(); int i = indexFor(hash); /** * * 遍历这个数组上的没一个节点,观察是否有相同的,如果有相同的节点那么就替换掉 * 判断两个对象是否相等(hashcode是否相等 + equals是否相同) */ for (Entry<K, V> e = table[i]; e != null ; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { e.value = (V) value; return key; } } table[i] = new Entry(key, value, table[i], hash); return null; }static class Entry<K,V> implements ICustomMap.Entry<K,V> { K key; V value; Entry<K, V> next; int hash; Entry(K k, V v, Entry<K, V> e, int h) { key = k; value = v; next = e; hash = h; } @Override public K getKey() { return key; } @Override public V getValue() { return value; } }
在Entry的实现类中,放了4个值,key,value,上一个节点next,和确定唯一性的hash值。
每put的一个新的元素进来的时候,
(1)先求在哪个一个数组下标下,indexFor(),
(2)然后判断是否重复
(3)把值放入下标中,并且把next指向前一个值形成链表
其实这种的方式是有一定的随机性的,如果hash冲突特别的多,hasmap就会退化成一个线性结构。
在jdk1.7的源码中,对此没有给出什么好的解决方法,在jdk1.8中个出的解决方案是,不采用链表,而是采用红黑树来存储hash冲突的数据,在查找的时候,时间复杂度从原先的O(n)将为O(logn)。我们会在下节介绍在jdk1.8中的hashmap的实现。
下面附上hashmap1.7 api的方法,已经自己对这个方法的理解:
hashMap有4个构造方法:
HashMap()HashMap(int initialCapacity)HashMap(int initialCapacity, float loadFactor)HashMap(Map<? extends K,? extends V> m)
最常用的是第一个什么都不传入,默认的数组容量大小为16,负载因子为0.75,负载因子的作用是在数组扩容时体现的,当一个hashmap的hash冲突过多的时候,如果数组不扩容,那么可能的情况就是数据线性存放,那么在查找的时候时间复杂度为O(n),所以当haspmap中的容量 > 数组容量(默认为16) * 负载因子(0.75),数组扩容2倍
void clear() 清除map中所有的元素Object clone() 返回hashmap浅拷贝的实例,该方法并非map中的方法。boolean containsKey(Object key) 是否包括某个keyboolean containsValue(Object value) 是否包括某个valueSet<Map.entry<K,V>> entrySet() 返回Map映射中的映射集合。此方法用与遍历mapV get(Object key) 用key查找值,返回值的范性数据boolean isEmpty() 是否为空 空为true 非空为 falseset<K> keySet() key的set集合K put(K key, V value) 存放键值对,返回键void putAll(Map<? extends K,? extends V> m) 存放一个map映射V remove(Object K) 移除一个键值对int size() 返回hashmap的键值对个数collection<V> values() 返回map的值的集合。
- JDK1.7 hashMap的简单实现
- jdk1.7 HashMap的实现原理
- 论Jdk1.7 HashMap实现
- JDK1.7的HashMap源码
- 基于jdk1.7的hashmap
- JDK1.8的hashmap实现与JDK1.7的差别导致的一个问题
- hashmap 的简单实现
- HashMap的简单实现
- JDK1.8HashMap源码的简单剖析(1)
- jdk1.7之HashMap
- HashMap jdk1.7
- HashMap环 JDK1.7
- 简单的hashmap的实现
- java HashMap的简单实现
- 手动HashMap的简单实现
- HashMap 在JDK1.7中的实现原理分析
- HashMap 在JDK1.8中的实现(与JDK1.7对比)
- HashMap的jdk1.8分析
- nyoj88汉诺塔一(快速幂)
- The study of slice in Python(20170911)
- openwrt 编译遇到的问题
- setInterval()定时器只执行一次的解决
- Hrbust-1815 小乐乐大逃亡(最长递增子序列)
- JDK1.7 hashMap的简单实现
- 在JAVA中封装JSONUtils工具类及使用
- 夜灵的Html笔记Day09——定位、渐变
- 定位、复制、清除数据有效性
- skynet co_create
- [笔记分享] [RPM] msm8610 RPM 流程
- 单链表删除头结点时出错解决方法
- CSS3二维变形
- JavaBean转换为Csv