快手二面 使用Java手写简易HashMap

public class MyHashMap<K,V>{
    /**
     * 做不到手撕红黑树
     * 基于1.7 简易实现
     * 数组下标 使用hashcode % n来计算
     * capcity 表示默认容量
     */
    class Node<K,V>{
        private K key;
        private V value;
        private Node<K,V> next; //表示链表的下一个节点
        public Node(K key,V value){
            this.key = key;
            this.value = value;
        }
        public Node(K key,V value,Node<K,V> next){
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }
    final int default_cap = 16;
    final float yinzi = 0.75f;
    private int size;
    Node<K,V>[] buckets; //链表桶

    public MyHashMap(){
        buckets = new Node[default_cap];
        this.size = 0;
    }
    public MyHashMap(int cap){
        buckets = new Node[cap];
        this.size = 0;
    }
    //getIndex 获取桶下标索引
    public int getIndex(K key,int length){
        int hashCode = key.hashCode();
        int index = Math.abs(hashCode % length);
        return index;
    }

    public void put(K key,V value){
        //考虑扩容 3*0.75
        if(size+1 >= buckets.length * yinzi){
            System.out.println(size+",cur:"+buckets.length * yinzi);
            resize();
        }
        //调用该方法真正去加入数据
        putValue(key, value,buckets);
    }
    
    public void putValue(K key, V value, MyHashMap<K, V>.Node<K, V>[] table) {
        int index = getIndex(key, table.length);
        Node node = table[index];
        if(node == null){
            table[index] = new Node<K,V>(key, value);
            size++;
            return;
        }else{
            while(node != null){
                //看一下有没有重复的 重复就覆盖掉
                if(node.key.hashCode() == key.hashCode() && (node.key == key || node.key.equals(key))){
                    //表示遇到重复的key了 覆盖
                    node.value = value;
                    return;
                }else{
                    node = node.next;
                }
            }
            //如果遍历完链表后没有重复的 那就在头部插入
            Node newhead = new Node<>(key, value, table[index]); //头插法 table[index]表示链表头
            table[index] = newhead;
            size++;
        }
    }
    private void resize() {
        Node<K,V>[] newBuckets = new Node[2*buckets.length];
        size = 0;  //resize的时候 这个需要重置为0
        for(int i=0;i<buckets.length;i++){
            if(buckets[i] == null) continue;
            Node<K,V> node = buckets[i];
            while(node != null){
                putValue(node.key, node.value, newBuckets);
                node = node.next;
            }
        }
        buckets = newBuckets;
    }

    public V get(K key){
        int index = getIndex(key, buckets.length);
        Node<K,V> node = buckets[index];
        if(node == null) return null;
        while(node != null){
            if(node.key.hashCode() == key.hashCode() && (node.key == key || node.key.equals(key))){
                return node.value;
            }else{
                node = node.next;
            }
        }
        return null;
    }

    public void remove(K key){
        int index = getIndex(key, buckets.length);
        Node<K,V> node = buckets[index];
        if(node == null) return;
        Node<K,V> pre = null;
        while(node != null){
            if(node.key.hashCode() == key.hashCode() && (node.key == key || node.key.equals(key))){
                Node<K,V> next = node.next;
                if(pre == null){
                    //表示删除的是头结点
                    buckets[index] = next;
                }else{
                    pre.next = next;
                }
                size--;
                return;
            }else{
                pre = node;
                node = node.next;
            }
        }
        return;
    }

    public int getSize(){
        return size;
    }

    static class Student{
        private String name;
        private Integer age;
        public Student(){
        }
        public Student(String name,Integer age){
            this.name = name;
            this.age = age;
        }
        public int hashCode(){
            return 100;
        }
        public String getName(){
            return name;
        }
    }
    public static void main(String[] args) {
        //MyHashMap<Integer,Integer> map = new MyHashMap<>(3);
        Student s1 = new Student("yyn", 20);
        Student s2 = new Student("yyn", 222);
        MyHashMap<Student,Integer> map = new MyHashMap<>(3);
        map.put(s1, 1);
        map.put(s2, 2);
        System.out.println(map.size);
        System.out.println("s1:"+map.get(s1));
        System.out.println("s2:"+map.get(s2));
        map.remove(s2);
        System.out.println(map.size);
        System.out.println("s1:"+map.get(s1));
        System.out.println("s2:"+map.get(s2));
        System.out.println(map.buckets.length);
    }


}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值