自己实现的HashMap

文章目录

简述

分享一个2年前自己实现的hashmap,查了下网上大多实现较为复杂,就献丑呈上。

MyHashMap

  • 接口类
package com.sunyard.unified.csrt.spring.map;

public interface Map<K,Y> {

     Y put(K k ,Y y);

     Y get(K k);

     int size();

     boolean isEmpty();

     interface Entry<K,Y> {
         Y getValue();

         K getKey();

         @Override
         int hashCode();
     }

}

  • 实现类
package com.sunyard.unified.csrt.spring.map;

/**
 * <p>HashMap</p>
 * 手写HashMap
 * 1.7 -> 数组 + 链表
 * 1.8 -> 数组 + 链表 + 红黑树
 * @author :chaotan.liu
 * @date :2020-07-30
 */
public class HashMap<K,V> implements Map<K,V> {

    Node<K,V>[] table = new Node[16];

    int size =0;
    @Override
    public V put(K k, V v) {
        int i = Math.abs( k.hashCode() % 16);
        Node<K,V> node = table[i];
        if(node == null){
            table[i] =  new Node<>(i,k,v,null);
        }else {
            //头部插入 ,个人认为插入效率高 ,内存冗余大 实测100000条数据耗时31毫秒 MemoryCost: 29297744KB
            table[i]=  new Node<>(i,k,v,node);
            //尾部插入 递归算法 100000条数据耗时15031毫秒 MemoryCost: 29297968KB
//            setNode(k, v, i, node);
            //尾部插入共耗时15101毫秒 MemoryCost: 29298032KB
//            while (node != null) {
//                if (node.getKey().hashCode() == k.hashCode()) {
//                    node.v = v;
//                    break;
//                } else {
//                    if (node.next == null) {
//                        node.next = new Node<>(i, k, v, null);
//                        break;
//                    } else {
//                        node = node.next;
//                    }
//                }
//            }
        }
        size++;
        return v;
    }

    /**
     * 递归实现尾部插入链表
     * @param k
     * @param v
     * @param index
     * @param e
     */
    private void setNode(K k, V v, int index, Node<K, V> e) {
        if( e.getKey().hashCode() == k.hashCode()){
            e.v = v;
        }
        if(e.next == null){
            e.next =  new Node<>(index,k,v,null);
        }
        else {
            setNode(k,v,index,e.next);
        }
    }



    private  Node<K, V> getNode(K k, Node<K, V> e) {
        if(e == null){
            return null;
        }
        if( e.getKey().hashCode() == k.hashCode()){
            return e;
        }else {
            return getNode(k,e.next);
        }
    }

    @Override
    public V get(K k) {
        if( isEmpty()){
            return null;
        }
        int i = Math.abs( k.hashCode() % 16);
        Node<K,V> node = table[i];
        if(node == null){
            return null;
        }
        //递归算法获取 共耗时12174毫秒
        //MemoryCost: 38265784KB
        Node<K, V> node1 = getNode(k, node);
        return node1 == null ? null : node1.getValue();
        // while方式获取 共耗时12287毫秒  MemoryCost: 38385472KB   两个方式差不多
//        while ( node != null){
//            if( node.getKey().hashCode() == k.hashCode()){
//                return node.getValue();
//            }
//            if(node.next != null){
//                node = node.next;
//            }else {
//                break;
//            }
//        }
//        return null;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        if(size() == 0){
            return true;
        }
        return false;
    }




    static class  Node<K,V> implements Map.Entry<K,V>{
        int hash;
        final K k;
        V v;
        Node<K,V> next;


        public Node(int hash, K k, V v, Node<K, V> next) {
            this.hash = hash;
            this.k = k;
            this.v = v;
            this.next = next;
        }

        @Override
        public V getValue() {
            return v;
        }

        @Override
        public K getKey() {
            return k;
        }

        @Override
        public final String toString() { return k + "=" + v; }
    }



}

  • 测试类
package com.sunyard.unified.csrt.spring.map;

//import java.util.Map;
//import java.util.HashMap;

/**
 * <p></p>
 *
 * @author :chaotan.liu
 * @date :2020-07-30
 */
public class MyMaptest {

    public static void main(String[] args) {
        Runtime r = Runtime.getRuntime();
        r.gc();//计算bai内存前先垃圾回收du一次
        Map<String,String> hashMap = new HashMap();
        long start = System.currentTimeMillis();
        long startMem = r.freeMemory(); // 开始Memory
        for (int i=0;i<100000;i++){
            hashMap.put(i+"优雅的key","柳晁潭"+i);

        }
        for (int i=0;i<100000;i++){
            hashMap.put(i+"优雅的key","吴思思"+i);

        }
        for (int i=0;i<100000;i++){
//            System.out.println(hashMap.get(i+"hahah"));
            System.out.println(hashMap.get(i+"优雅的key"));
        }
        long end = System.currentTimeMillis();
        long endMem =r.freeMemory(); // 末尾Memory
        System.out.println("共耗时"+(end-start)+"毫秒");
        System.out.println("MemoryCost: "+String.valueOf((startMem- endMem))+"KB");
    }
}
//共耗时14099毫秒
//MemoryCost: 39800888KB
//hash 共耗时533毫秒
//MemoryCost: 28301384KB

唠嗑

自己实现的简单map速率确实差了很多,占用的空间也较大,比较hashmap不仅仅实现了简单的存取。
只用于理解hashmap的实现原理,感兴趣的可以撸下来康康。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值