手写HashMap

    看完jdk 1.7和1.8的源码之后, 受源码的启发 手写一下HashMap,主要体会思想和原理

基于Arraylist集合方式实现:
package com.shanheyongmu.map;

import java.util.ArrayList;
import java.util.List;

/**
 * 基于Arraylist集合方式实现
 * @ClassName ArraylistHashMap
 **/
public class ArraylistHashMap<K, V> {
    private List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>();

    class Entry<K, V> {
        K k;
        V v;
        Entry next;

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

    public void put(K k, V v) {
        entries.add(new Entry<>(k, v));
    }

    public V get(K k) {
        for (Entry<K, V> entry :
                entries) {
            if (entry.k.equals(k)) {
                return entry.v;
            }
        }
        return null;
    }

    public static void main(String[] args) {
        ArraylistHashMap<String, String> arraylistHashMap = new ArraylistHashMap<>();
        arraylistHashMap.put("blog", "blog1");
        arraylistHashMap.put("test", "test1");
        System.out.println(arraylistHashMap.get("test"));
    }
}

总结:

根据key查询时间复杂度为o(n),效率非常低。

 

基于数组下标方式实现HashMap:

package com.shanheyongmu.map;

/**
 * 基于数组下标方式实现HashMap
 * @param <K>
 * @param <V>
 */
public class ExtHashMap<K, V> {
    private Entry[] entrys = new Entry[10000];

    class Entry<K, V> {
        public K k;
        public V v;
        public Entry(K k, V v) {
            this.k = k;
            this.v = v;
        }
    }

    public void put(K k, V v) {
//取模方式
int index = k.hashCode() % entrys.length; entrys[index] = entrys[index]; } public V get(K k) { int index = k.hashCode() % entrys.length; return (V) entrys[index].v; } public static void main(String[] args) { ExtHashMap<Object, String> hashMap = new ExtHashMap<>(); hashMap.put("a", "a"); hashMap.put(97, "97"); System.out.println(hashMap.get("a")); } }
 

 

Hash碰撞问题:
原因:hashcode值相同,内容值不同
通过jdk HashMap代码Entry<k,v> next和 put     上面代码还是有欠缺没有的问题  解决hash碰撞问题和增加遍历链表数据和key为null  增加代码如下
 
基于数组+链表方式实现:
package com.shanheyongmu.map;

/**
 * 基于数组+链表方式实现
 * @param <K>
 * @param <V>
 */
public class ExtHashMap<K, V> {
    private Entry[] entrys = new Entry[10000];

    class Entry<K, V> {
        public K k;
        public V v;
        Entry<K,V> next;

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

    public void put(K k, V v) {
        //数组 + 链表实现 hash算法

    int index = k == null ? 0 : k.hashCode() % objects.length;

   //判断key是否冲突
        Entry oldEntry = entrys[index];
        if(oldEntry == null){
             //key 没有发生hash碰撞的问题
            entrys[index] = new Entry<K,V>(k,v);
        }else {
            // 发生hash碰撞则存放到链表后面
            oldEntry.next = new Entry<K,V>(k,v);
        }
        entrys[index] = entrys[index];
    }

    public V get(K k) {
    //遍历链表数据
        int index = k == null ? 0 : k.hashCode() % entrys.length;
        for (Entry<K, V> oldEntry = entrys[index]; oldEntry != null; oldEntry = oldEntry.next) {
            if (oldEntry.k == null || oldEntry.k.equals(k)) {
                return oldEntry.v;
            }
        }
        return null;
    }


    public static void main(String[] args) {
        ExtHashMap<Object, String> hashMap = new ExtHashMap<>();
        hashMap.put("a", "a");
        hashMap.put(97, "97");
        System.out.println(hashMap.get("a"));
    }
}

 

 

 

 
 

 

 




 

posted @ 2023-02-03 14:01  山河永慕~  阅读(9)  评论(0编辑  收藏  举报