手动实现一个HashMap类----new一个HashMap对象时竟然做了这些事情

好多面试官都会问到HashMap的底层原理,说明对应届生是非常看重基础问题的。今天研究了一下(一天)源码(确实很头大啊啊啊啊),根据JDK1.7写了一个简单的Demo,如有错误请大家帮忙指正。Demo后面我整理了一些关于HashMap的面试题↓↓↓

public class MyHashMap<K,V> {
    //定义一个数组
    private Entry[] table;
    //设置容量为 8
    private static Integer CAPACITRY = 8;
    private int size = 0;
    //构造方法 创建MyHashMap对象时就初始化一个长度为8的Entry[]数组
    public MyHashMap() {
        this.table = new Entry[CAPACITRY];
    }
    //entry的个数
    public int size() {
        return size;
    }

    public Object get(Object key) {
        int hash = key.hashCode();
        int i = hash % CAPACITRY;
        for (Entry<K,V> entry = table[i]; entry != null; entry = entry.next) {
            if (entry.k.equals(key)) {
                return entry.v;
            }
        }

        return null;
    }

    public V put(K key, V value) {
        //计算key的哈希值
        int hash = key.hashCode();
        //模拟jdk1.7计算出索引
        int i = hash % CAPACITRY;
        //对索引i处的链表做遍历,next是Entry类中Entry型的成员属性
        for (Entry<K,V> entry = table[i]; entry != null; entry = entry.next) {
            //如果key值已经存在,则返回旧的value
            if (entry.k.equals(key)) {
                V oldValue = entry.v;
                entry.v = value;
                return oldValue;
            }
        }

        addEntry(key, value, i);
        return null;

    }

    private void addEntry(K key, V value, int i) {
        //这里的操作就是把链表下移
        Entry entry = new Entry(key, value, table[i]);
        //使新的entry在链表头部(头插法)
        table[i] = entry;
        size++;
    }

    //每一个键值对以entry的形式保存
    class Entry<K,V> {
        private K k;
        private V v;
        private Entry next;

        public Entry(K k, V v, Entry next) {
            this.k = k;
            this.v = v;
            this.next = next;
        }

        public K getK() {
            return k;
        }

        public void setK(K k) {
            this.k = k;
        }

        public V getV() {
            return v;
        }

        public void setV(V v) {
            this.v = v;
        }

        public Entry getNext() {
            return next;
        }

        public void setNext(Entry next) {
            this.next = next;
        }
    }
    //测试
    public static void main(String[] args) {
        MyHashMap<String, String> myHashMap = new MyHashMap<>();
        for (int i = 0; i < 10 ; i++) {
            myHashMap.put("Crown" + i, "10" + i);
            System.out.println(myHashMap.get("Crown" + i));
        }
    }

}

HashMap常见面试题:

  1. HashMap的底层数据结构?
  2. HashMap的存取原理?
  3. Java7和Java8中HashMap的区别?
  4. 默认初始化大小是多少?为什么大小都是2的幂?
  5. HashMap的扩容方式?负载因子是多少?
  6. HashMap的主要参数都有哪些?
  7. HashMap是怎么处理hash碰撞的?
  8. 可以跟我讲一下红黑树吗?为什么要用到红黑树?
  9. HashMap为什么不是线程安全的?涉及线程安全的场景怎么办?

相信大家看了这个小Demo对这些问题有了一定的了解,再去看看源码研究下就可以轻松应对面试官,祝各位面试顺利进大厂哈哈哈。


版权声明:本文为Crown_123原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。