Java简单实现HashMap

构造map接口:

package com.extHashMap;

import sun.awt.SunHints;

public interface ExtMap<K,V> {

    V put(K k,V v);

    V get(K k );

    interface Entry<K,V>{
        K getKey();
        V getValue();
        V setValue(V v);
    }
}

构造HashMap:

package com.extHashMap;

/*
数组+单向链表的方式实现hashmap
 */
public class ExtHashMap<K, V> implements ExtMap<K, V> {

    Node<K, V>[] tables = null;//懒加载,需要时才加载

    //map长度
    int size;
    // 3.HashMap默认负载因子,负载因子越小,hash冲突机率越低, 根据每个链表的个数
    float DEFAULT_LOAD_FACTOR = 0.75f;
    // 4.table默认初始大小 16
    static int DEFAULT_INITIAL_CAPACITY = 16; // 16

    static int CAPACITY_NUM = 1;

    @Override
    public V put(K k, V v) {
        //判断当前map是否为kong
        if (null == tables) {
            //按照默认长度创建map容器
            tables = new Node[DEFAULT_INITIAL_CAPACITY];
        }
        //判断是否需要扩容
        if (size >= (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR * CAPACITY_NUM)) {
            //扩容
            resize();
        }
        //根据key值计算下标,获取当前node
        int i = k.hashCode();
        int index = i % (tables.length);
        Node node = tables[index];
        //判读是否存在hash冲突
        if (node != null) {
            //存在hash冲突
            //遍历当前node链表
            Node newNode = node;//引用传递
            //假如只存在一个节点
            while (newNode != null) {
                //值或者引用相等
                if (newNode.getKey().equals(k) || newNode.getKey() == k) {
                    //覆盖
                    return (V) newNode.setValue(v);
                } else {
                    //添加,七上八下原则,新值在最前面
                    if (newNode.next == null) {
                        // 说明遍历到最后一个node ,添加node
                        node = new Node(k, v, node);
                        size++;
                    }
                }
                newNode = newNode.next;
            }
        } else {
            //没有发生hash冲突、
            node = new Node(k, v, null);
            size++;
        }
        tables[index] = node;
        return null;
    }

    private void resize() {
        //扩容
        Node[] nodes = new Node[(DEFAULT_INITIAL_CAPACITY << 1) * CAPACITY_NUM];
        for (int i = 0; i < tables.length; i++) {
            Node<K, V> table = tables[i];//获取链表
            while (table != null){
                K key = table.getKey();
                int j = key.hashCode();
                int index = j % (nodes.length);//新数组索引获取
                //如果当前nodes[index]存在数据,则需要执行如下代码,如果不存在,正好把下一个置空
                table.next = nodes[index];
                //把旧节点的当前链表赋值给扩容后数组的指定索引位置
                nodes[index] = table;
                table = table.next;
            }

        }
        tables = nodes;



//        Node<K, V> table = tables[oldIndex];
//        Node<K, V> tmpTable = table;
//        while (tmpTable != null) {
//
//            tmpTable = tmpTable.next;
//        }


        CAPACITY_NUM++;
        nodes = null;/// 赋值为null---为了垃圾回收机制能够回收


    }

    // 测试方法.打印所有的链表元素
    void print() {

        for (int i = 0; i < tables.length; i++) {
            Node<K, V> node = tables[i];
            System.out.print("下标位置[" + i + "]");
            while (node != null) {
                System.out.print("[ key:" + node.getKey() + ",value:" + node.getValue() + "]");
                node = node.next;
                // if (node.next != null) {
                // node = node.next;
                // } else {
                // // 结束循环
                // node = null;
                // }

            }
            System.out.println();
        }

    }

    public Node getTableByIndex(K k) {
        int i = k.hashCode();
        int index = i % (tables.length);
        return tables[index];
    }

    @Override
    public V get(K k) {
        Node<K, V> table = getTableByIndex(k);
        while (table !=null){
            if(table.getKey().equals(k) || table.getKey() == k){
                return table.getValue();
            }
            table = table.next;
        }
        return null;
    }

    public static void main(String[] args) {
        ExtHashMap<String, String> map = new ExtHashMap<>();
        map.put("a", "b");
        map.put("a", "g");
        map.put("b", "h");
        map.print();
        System.out.println(map.get("b"));

    }
}

class Node<K, V> implements ExtMap.Entry<K, V> {

    // 存放Map 集合 key
    private K key;
    // 存放Map 集合 value
    private V value;
    // 下一个节点Node
    Node<K, V> next;

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

    @Override
    public K getKey() {
        return this.key;
    }

    @Override
    public V getValue() {
        return this.value;
    }

    @Override
    public V setValue(V v) {
        //设置新值,返回老的值
        V oldValue = this.value;
        this.value = v;
        return oldValue;
    }
}

单元测试:

package com.extHashMap;


public class Test003 {

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        // 基于什么原则 后进选出 非公平锁与公平锁
        ExtHashMap extHashMap = new ExtHashMap<String, String>();
        extHashMap.put("1号", "1号");// 0
        extHashMap.put("2号", "1号");// 1
        extHashMap.put("3号", "1号");// 2
        extHashMap.put("4号", "1号");// 3
        extHashMap.put("6号", "1号");// 4
        extHashMap.put("7号", "1号");
        extHashMap.put("14号", "1号");
        extHashMap.put("22号", "1号");
        extHashMap.put("26号", "1号");
        extHashMap.put("27号", "1号");
        extHashMap.put("28号", "1号");
        extHashMap.put("66号", "66");
        System.out.println("扩容前数据....");
        extHashMap.print();
        System.out.println("扩容后数据....");
        extHashMap.put("30号", "1号");


        extHashMap.put("31号", "1号");
        extHashMap.put("66号", "123466666");
        extHashMap.print();
        // 修改3号之后
        System.out.println(extHashMap.get("66号"));
        // System.out.println("扩容之前获取数据:" + extHashMap.get("1号"));
        // extHashMap.print();
        // System.out.println();
        // // extHashMap.put(14 + "号", 14 + "号");
        // // extHashMap.put(1 + "号", "4444号");
        // System.out.println("扩容之后获取数据:" + extHashMap.get("1号"));
        // extHashMap.print();

    }

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值