HashMap 源码分析
来源:互联网 发布:淘宝的安静一键宏好吗 编辑:程序博客网 时间:2024/06/07 07:18
首先,我们先说一下HashMap的底层结构是数组加链表,也就是说它的底层我们可以使用LinkedList和数组进行实现,下边我们来看看他们的源码:
①我们像HashMap一样定义一个Node节点,来指定当前元素的key与
value
public class Node<K,V> { private K key; private V value; 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; }}
好了,以上是我们定义的节点,接下来就来看看它的一些基本用法实现吧:
/** * * @author Mrzhang * 注:HashMap 底层实现-->数组+链表 LinkedList */public class MyHashMapTwo<K, V> {// 存放数据数组,这里是随便定义的大小,如果有兴趣的话,可以去看看源码是怎么定义的private LinkedList<Node<K, V>> arr[] = new LinkedList[100];private int size; /** * 获取容器存放元素个数 */ public int size() { return size; } /** * 增加一个元素 1.根据hashcode判断数组对应位置是否为空(为空则new) * 2.不为空:判断对用链表是否有相同的key,如果key相同,则将对应的 * value改变 如果key不同,则新加一个元素 3.最后size++ * * @param args */ public void put(K key, V value) { int index = hash(key); Node<K, V> node = new Node<K, V>(); node.setKey(key); node.setValue(value); if (arr[index] == null) { LinkedList<Node<K, V>> linkedList = new LinkedList<Node<K, V>>(); linkedList.add(node); arr[index] = linkedList; } else { for (int count = 0; count < arr[index].size(); count++) { if (key.equals(arr[index].get(count).getKey())) { arr[index].get(count).setValue(value); } } arr[index].add(node); } size++; } /** * 删除 * * @param args */ public void remove(K key) { int index = hash(key); if (arr[index] == null) { throw new NullPointerException(); } else { for (int count = 0; count < arr[index].size(); count++) { if (key.equals(arr[index].get(count).getKey())) { arr[index].remove(count); size--; } } } } /** * 查看 * * @param args */ public V get(K key) { int index = hash(key); if (arr[index] != null) { for (int count = 0; count < arr[index].size(); count++) { if (key.equals(arr[index].get(count).getKey().toString())) { return arr[index].get(count).getValue(); } } } return null; } /** * 获取hashCode码 * * @param key * @return */ private int hash(Object key) { int index = Math.abs(key.hashCode() % arr.length); return index; } /** * 判断是否包含相应的key */ public boolean cotainsKey(K key) { int index = hash(key); if (arr[index] != null) { LinkedList<Node<K, V>> linkedList = arr[hash(key)]; for (int count = 0; count < linkedList.size(); count++) { if (key.equals(linkedList.get(count).getKey())) { return true; } } } return false; } /** * 判断是否包含相应的Value 注:对于value的查询,应该遍历容器 */ public boolean cotainsValue(V value) { for (int count = 0; count < arr.length; count++) { if (arr[count] != null) { for (int index = 0; index < arr[count].size(); index++) { if (arr[count].get(index).getValue().equals(value)) { return true; } } } } return false; } public static void main(String[] args) { /** * 测试 */ MyHashMapTwo<String, String> myHashMapTwo = new MyHashMapTwo<String, String>(); myHashMapTwo.put("zhang", "三21"); myHashMapTwo.put("zhang1", "三2"); myHashMapTwo.put("zhang2", "三1"); myHashMapTwo.put("zhang3", "wu"); System.out.println(myHashMapTwo.size()); System.out.println(myHashMapTwo.get("zhang2")); myHashMapTwo.remove("zhang"); System.out.println(myHashMapTwo.get("zhang3")); System.out.println(myHashMapTwo.size()); System.out.println(myHashMapTwo.get("zhang")); System.out.println(myHashMapTwo.cotainsKey("zhang")); System.out.println(myHashMapTwo.cotainsValue("wu")); }}
哎呀,看着这个纯粹的代码,排版也不是特别好,我也有点小尴尬,但是大家可以把代码复制粘贴下去看看,其实显而易见,这里这要讲解了HashMap的增删查以及containsKey等方法,修改的话,哈哈哈,大家都知道,直接覆盖。本来是想着重写一个hashCode与equals方法的,但是我觉得这里的话,直接调用其他类的就行了,毕竟其他类也有实现(Object,LinkedList,String)。之前也有以前文章详细讲了下HashCode与equals,大家也可以去看看。
好了,就说这么多吧,代码也就这样,相信你可以在十分钟之内读完并理解,因为本身也不是很难。
最后在给大家关于hashMap存放元素的图,以便大家更好的理解:
0 0
- 源码分析:HashMap
- 源码分析:HashMap
- HashMap源码分析
- HashMap 源码分析
- HashMap源码分析
- HashMap LinkedHashMap源码分析
- HashMap源码分析
- HashMap 源码分析
- HashMap源码分析
- HashMap源码分析
- HashMap源码分析
- Java HashMap 源码分析
- HashMap源码分析
- java HashMap源码分析
- 源码分析HashMap
- HashMap源码分析
- HashMap源码分析
- HashMap源码分析
- 【JZOJ5050】【GDOI2017模拟一试4.11】颜色树
- python-cookbook学习笔记五
- Tomcat修改get提交请求乱码
- X86反汇编速成班(条件指令,分支指令、重复指令、寄存器等)
- java.lang.ClassNotFoundException: com.jdbc.mysql.Driver
- HashMap 源码分析
- POJ
- 更改对于登录sa失败的解决方法
- Android getReadableDatabase和getWriteableDatabase的区别
- linux常用命令
- POJ 1163 The Triangle 【简单题】
- 【IO进程】设置进程调度策略(实时进程)
- Choose unique values for the 'webAppRootKey' context-param in your web.xml files 解决办法
- 【开源Linux学习笔记002 Linux网络管理】