博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简易HashMap实现
阅读量:6090 次
发布时间:2019-06-20

本文共 4182 字,大约阅读时间需要 13 分钟。

为了更好的理解HashMap线程不安全的根源,这里提供了HashMap的简易实现:

 

package map.test;import org.apache.commons.lang3.StringUtils;/** * Author:yepei@meituan.com * Date:2017/7/5 * Time:15:45 * ------------------------------------ * Desc: */public class HashMp {    private transient Node[] entries;//数组    private transient float loadFactor;    private transient int size;    public static void main(String[] args) {        HashMp map = new HashMp(2, 0.75f);        map.put(3, "A");        System.out.println(map);        map.put(5, "B");        map.put(7, "C");        map.put(11, "D");        map.put(9, "E");        map.put(12, "F");        map.put(17, "G");        map.put(22, "H");        map.put(24, "I");        map.put(25, "I");        System.out.println(map);        String s1 = map.get(22);        String s2 = map.get(25);        String s3 = map.get(0);    }    public HashMp(int capacity, float loadFactor) {        this.entries = new Node[capacity];        this.loadFactor = loadFactor;    }    public HashMp() {        this(16, 0.75f);    }    public String put(int key, String value) {        Node n = new Node(key, value);        //算Hash值,为简单起见,hash值        int i = n.getIndex(entries.length);        Integer thisKey = key;        //查找是否有重复: hashCode相等,且equals方法相等的        for (Node old = entries[i]; old != null; old = old.next) {            Integer oldKey;            //hash相同,且equals返回true,证明有重复值插入,直接替换掉旧值            if (old.getHash() == n.getHash() && ((oldKey = old.key) == key || thisKey.equals(oldKey))) {                String oldValue = old.value;                old.value = value;//替换成新值                return oldValue;//返回旧值            }        }        //该key不存在,需要增加一个结点        addEntry(n);        return null;    }    public String get(int key) {        int idx = new Node(key, null).getIndex(entries.length);        Integer thisKey = key;        //查找是否有重复: hashCode相等,且equals方法相等的        for (Node old = entries[idx]; old != null; old = old.next) {            Integer oldKey = old.key;            if (thisKey == oldKey || thisKey.equals(oldKey)) {                return old.value;            }        }        return null;    }    private void addEntry(Node n) {        int oldLen = entries.length;        int targetIdx = n.getIndex(oldLen);        n.next = entries[targetIdx];        entries[targetIdx] = n;//插入到链首        if (size++ >= oldLen * loadFactor) {            resize(2 * oldLen);        }    }    private void resize(int newCapacity) {        Node[] old = entries;        Node[] newMap = new Node[newCapacity];        for (int j = 0; j < old.length; j++) {            Node e = old[j];            if (e == null) {                continue;            }            old[j] = null;//老表中的元素置为Null                        //注意:该过程会将同一个bucket中的元素逆置,因为总是将元素插在了新表的头部。            //但不是就地逆置,因为将元素逐个copy到了新的链表中            do {                Node next = e.next;//暂存尾链表(去掉head的链表)                int i = e.getIndex(newCapacity);//得到将在新表中存储的位置                e.next = newMap[i];//切断指针,重新指向新表的表头(可能为null)                newMap[i] = e;//将e插入到新链表头部                e = next;//重新将e赋值为尾链表的头,对尾链表继续“切断指针,插入新表头”            } while (e != null);        }        entries = newMap;    }    @Override    public String toString() {        StringBuilder sb = new StringBuilder("[");        int i = 0;        for (Node n : entries) {            sb.append(i++).append("{").append(n).append("}, ");        }        return StringUtils.removeEnd(sb.toString(), ", ") + "]";    }    static class Node {        int key;        String value;        Node next;        Node(int key, String value) {            this.key = key;            this.value = value;        }        int getIndex(int tableLength) {            return getHash() % tableLength;        }        //为方便起见,hash值直接取该对象的key        int getHash() {            return key;        }        @Override        public String toString() {            return "(" + key + "," + value + ")——>" + next;        }    }}

  

参考

HashMap源码解读:http://www.xiaomager.com/category/program/java/hashmap

Hashcode生成原理:http://www.cnblogs.com/godtrue/p/6395098.html

HashMap存在的三大并发问题:https://my.oschina.net/xianggao/blog/393990

转载于:https://www.cnblogs.com/yepei/p/7122527.html

你可能感兴趣的文章
使用scikit-learn解决文本多分类问题(附python演练)
查看>>
2018 年最值得关注的 JavaScript 趋势
查看>>
什么是区块链?超级账本 Brian Behlendorf 从五个方面教你认识
查看>>
Linux中的帮助功能
查看>>
针对Android的Pegasus恶意软件版本和针对iOS的有什么不同?
查看>>
全局探色器
查看>>
Hive Export和Import介绍及操作示例
查看>>
http://mongoexplorer.com/ 一个不错的 mongodb 客户端工具。。。
查看>>
上传jar包到nexus私服
查看>>
Why Namespace? - 每天5分钟玩转 OpenStack(102)
查看>>
Project:如何分析项目中的资源分配情况
查看>>
HDU 4803 Poor Warehouse Keeper (贪心+避开精度)
查看>>
小错误汇总
查看>>
Spring源码系列 — Envoriment组件
查看>>
java正则表达式去除html标签,Java中正则表达式去除html标签
查看>>
使用Cobbler批量部署Linux操作系统
查看>>
zabbix企业应用之服务端与客户端的安装
查看>>
实例讲解遗传算法——基于遗传算法的自动组卷系统【理论篇】
查看>>
无法在web服务器上启动调试。调试失败,因为没有启用集成windows身份验证
查看>>
Bat相关的项目应用
查看>>