数据结构之手写HashMap

导读:本篇文章讲解 数据结构之手写HashMap,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一:HashMap和HashSet特点

HashMap
1)HashMap的key和value都可以为null,key不可以重复,只要key一样就会把之前的覆盖掉。
2)HashMap是无序的,线程不安全的
3)Hashtable是Map的古老实现类;线程安全的,效率低;因为锁的是整个map。不可以存储null的key和value
HashSet
1)HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
2)HashSet 允许有 null 值。
3)HashSet 是无序的,即不会记录插入的顺序。
4)HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
5)HashSet 实现了 Set 接口。

二:HashMap

1.定义map接口

public interface Map<K,V> {
    /**
     * put方法
     * @param k
     * @param v
     * @return
     */
    V put(K k,V v);
    /**
     * get方法
     * @param k
     * @return
     */
    V get(K k);
    /**
     * map长度
     * @return
     */
    int size();
    /**
     *
     * @param <K>
     * @param <V>
     */
    interface Entry<K,V>{
        /**
         * 获取key
         * @return
         */
        K getKey();
        /**
         * 获取value
         * @return
         */
        V getValue();
    }
}

2.定义HashMap<K,V>并且实现Map<K,V>

    Entry<K,V>[] table = null;
    int size = 0;
    public HashMap(){
        table = new Entry[16];
    }
  • HashMap底层就是一个数组,默认长度是16

3.对hashMap的key进行hash算法

    private int hash(K k){
        int index = k.hashCode() % 16;
        return index>=0?index:-index;
    }
  • 对hashMap的key值进行hash算法,取模算出下标

4.重写get和put方法

    @Override
    public V get(K k) {
        int index = hash(k);
        Entry<K, V> entry = findValue(table[index],k);
        return entry==null?null:entry.getValue();
    }

    @Override
    public V put(K k, V v) {
        int index = hash(k);
        Entry<K, V> entry = table[index];
        if(null == entry){
            table[index] = new Entry<>(k, v, index, null);
            size++;
        } else {
            table[index] = new Entry<>(k, v, index, entry);
        }
        return table[index].getValue();
    }
    @Override
    public int size() {
        return 0;
    }

1.key进行hash,取模算出index下标
2.找到数组对应的节点对象,判断对象是否为空
3.如果为空,直接返回空对象
4.如果不为空,用查出来的k和当前k做比较
1):如果相等,直接返回数据
2):如果不相等,查询next是否为空,为空直接返回
3):如果不为空,查询取出来的key和当前的key是否相等,直到相等为止

5.在entry数组中,找到指定key所对应的value值

 public Entry<K,V> findValue(Entry<K, V> entry,K k){
        if (k.equals(entry.getKey()) || k == entry.getKey()){
            return entry;
        } else {
            if( entry.next != null){
                return findValue(entry.next, k);
            }
        }
        return null;
    }

6.重写entry数组

 class Entry<K,V> implements Map.Entry<K,V>{
        K k;
        V v;
        int index;
        Entry<K,V> next;
        public Entry(K k, V v, int index, Entry<K, V> next) {
            this.k = k;
            this.v = v;
            this.index = index;
            this.next = next;
        }
        @Override
        public K getKey() {
            return k;
        }
        @Override
        public V getValue() {
            return v;
        }
    }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84098.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!