JAVA数据结构之哈希表「建议收藏」

hash表的优缺点hash表比树形结构快的原因,表的是位置是计算出来的通过hash函数,满足随机插入的结构。但是在有该优点的情况下,需要考虑哈希冲突本例结构中采用链地址法【在hash表的每一个表单元,都是链表结构,发生冲突的元素,自动加入链表】在jdk8以前采用的是链表解决,在jdk8之后,在处理哈希冲突时,先采用链表,当链表中size大于8时,转化为树形结构,…

大家好,又见面了,我是你们的朋友全栈君。

hash表的优缺点

hash表比树形结构快的原因,表的是位置是计算出来的通过hash函数,满足随机插入的结构。但是在有该优点的情况下,需要考虑哈希冲突

本例结构中采用链地址法【在hash表的每一个表单元,都是链表结构,发生冲突的元素,自动加入链表】

在jdk8以前采用的是链表解决,在jdk8之后,在处理哈希冲突时,先采用链表,当链表中size大于8时,转化为树形结构,采用的红黑树结构。

这里写图片描述
这里写图片描述

//不需要像二分搜索树一样 键值实现可比较,只需要能实现hashCode 但每一个对象都是继承自Object 所以都有hashCode方法
public class HashTable<K, V> {
    private final int[] capacity
            = {
  
  53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
            49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
            12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741};
    private static final int upperTol = 10;
    private static final int lowerTol = 2;
    private int CapacityIndex = 0;


    private TreeMap<K, V>[] hashtable;
    private int M;//设置哈希表数组长度,选择一个合适的素数
    private int size;//已经存储的元素个数

    public HashTable() {
        this.M = capacity[CapacityIndex];
        this.size = 0;
        hashtable = new TreeMap[M];//只是开出了空间,还需要对每个空间进行实例化
        for (int i = 0; i < M; i++) {
            hashtable[i] = new TreeMap<>();
        }
    }


    private int hash(K key) {
        return (key.hashCode() & 0x7fffffff) % M;//消除掉key对应的hashCode的符号
    }

    public int getSize() {
        return size;
    }

    public void add(K key, V value) {
        TreeMap<K, V> map = hashtable[hash(key)];
        if (map.containsKey(key)) {
            map.put(key, value);
        } else {
            map.put(key, value);
            size++;
        }
        //判断数组越界问题
        if (size >= upperTol * M && CapacityIndex + 1 < capacity.length) {
            CapacityIndex++;
            resize(capacity[CapacityIndex]);
        }
    }

    public V remove(K key) {
        TreeMap<K, V> map = hashtable[hash(key)];
        V ret = null;
        if (map.containsKey(key)) {
            ret = map.remove(key);
            size--;
        }

        if (size < lowerTol * M && CapacityIndex - 1 >= 0) {
            CapacityIndex--;
            resize(capacity[CapacityIndex]);
        }
        return ret;
    }

    public void set(K key, V value) {
        TreeMap<K, V> map = hashtable[hash(key)];
        if (!map.containsKey(key)) {
            throw new IllegalArgumentException(key + "doesn't exist");
        } else {
            map.put(key, value);
        }
    }

    public boolean contains(K key) {
        return hashtable[hash(key)].containsKey(key);
    }

    public V get(K key) {
        return hashtable[hash(key)].get(key);
    }

    private void resize(int newM) {
        TreeMap<K, V>[] newHashTable = new TreeMap[newM];
        for (int i = 0; i < newM; i++) {
            newHashTable[i] = new TreeMap<>();
        }
        int oldM = M;
        this.M = newM;//在hash()中会用到新的的M
        //必须重新给M赋值!!!
        for (int i = 0; i < oldM; i++) {
            TreeMap<K, V> map = hashtable[i];
            for (K key : map.keySet()) {
                newHashTable[hash(key)].put(key, map.get(key));
            }
        }
        this.hashtable = newHashTable;
    }
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126574.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 网络安全系列之1 SYN洪水***

    网络安全系列之1 SYN洪水***

    2021年8月31日
    62
  • 猪脸识别,赢取30万大赛奖金[通俗易懂]

    猪脸识别,赢取30万大赛奖金[通俗易懂]买个彩票,无论中奖与否,完全靠运气。大数据与AI大赛,冠军奖金30w,咱们技术人靠实力。事件:JDD-2017京东金融全球数据探索者大赛一场面向全球AI与数据人才的人…

    2022年6月21日
    31
  • idea2021.9激活码[最新免费获取]

    (idea2021.9激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~S32PGH0SQB-eyJsaWNlbnNlSWQiOi…

    2022年3月26日
    54
  • android 定时器

    android 定时器在Android开发中,定时器一般有以下3种实现方法:一、采用Handler与线程的sleep(long)方法二、采用Handler的postDelayed(Runnable,long)方法三、采用Handler与timer及TimerTask结合的方法下面逐一介绍:一、采用Handle与线程的sleep(long)方法Handler主要用来处理接受到的消

    2022年7月25日
    9
  • 几款永久免费内网穿透,好用且简单(内网穿透教程)

    对于网络用户来说,一定都经历过出门在外无法直接在外网访问内网、或是难以部署异地远程桌面,因此心急如焚的情况;对于企业来说,无论是财务管理软件难以将分店信息同步到总部进行统计汇总、还是员工出差在外或在家里就不能访问企业内部办公系统,都极大地影响了公司整体效率;对于个人开发者来说,微信小程序或者在线支付系统等开发环境往往需要一个可以外部访问的公网环境进行调试,而大多数的企业网络都被运营商做了转发设置,…

    2022年4月16日
    92
  • 安卓设备转移代码_从安卓设备转移数据到苹果手机

    安卓设备转移代码_从安卓设备转移数据到苹果手机JihosoftPhoneTransfer提供一键式解决方案,可在Android和iOS设备之间传输数据,甚至可以轻松备份和恢复您的手机数据。这是非常容易使用。下载电话数据传输并完成安装过程后,您应该看到如下主窗口:第1部分:如何将数据从电话传输到电话1,将您的两个设备连接到计算机在主页上,点击“手机到手机”标签,并使用USB线将两台设备(Android或iOS)连接到计算机。通过电话转接连接…

    2022年9月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号