JAVA 容器学习之HashMap

HashMap采用哈希算法实现,是Map接口最常用的实现类。 由于底层采用了哈希表存储数据,我们要求键不能重复,如果发生重复,新的键值对会替换旧的键值对。 HashMap在查找、删除、修改方面都有非常高的效率。

PS:
HashTable类和HashMap用法几乎一样,底层实现几乎一样,只不过HashTable的方法添加了synchronized关键字确保线程同步检查,效率较低。

HashMap与HashTable的区别

  1. HashMap: 线程不安全,效率高。允许key或value为null。

  2. HashTable: 线程安全,效率低。不允许key或value为null。

主要学HashMap的实现
在这里插入图片描述
我们的目的是将”key-value两个对象”成对存放到HashMap的Entry[]数组中。参见以下步骤:

  (1) 获得key对象的hashcode

       首先调用key对象的hashcode()方法,获得hashcode。

  (2) 根据hashcode计算出hash值(要求在[0, 数组长度-1]区间)

       hashcode是一个整数,我们需要将它转化成[0, 数组长度-1]的范围。我们要求转化后的hash值尽量均匀地分布在[0,数组长度-1]这个区间,减少“hash冲突”

       i. 一种极端简单和低下的算法是:

       hash值 = hashcode/hashcode;

       也就是说,hash值总是1。意味着,键值对对象都会存储到数组索引1位置,这样就形成一个非常长的链表。相当于每存储一个对象都会发生“hash冲突”,HashMap也退化成了一个“链表”。

       ii. 一种简单和常用的算法是(相除取余算法):

       hash值 = hashcode%数组长度

       这种算法可以让hash值均匀的分布在[0,数组长度-1]的区间。 早期的HashTable就是采用这种算法。但是,这种算法由于使用了“除法”,效率低下。JDK后来改进了算法。首先约定数组长度必须为2的整数幂,这样采用位运算即可实现取余的效果:hash值 = hashcode&(数组长度-1)。

       iii. 如下为我们自己测试简单的hash算法:
   		System.out.println(h&(length-1));
   		//length为2的整数幂情况下,和取余的值一样
   	    System.out.println(h%length);//取余数

代码:

    private int getHash(int h, int length){
        return h&(length - 1);
    }

    public void put(K key, V value){
        HashNode newNode = new HashNode(getHash(key.hashCode(), table.length), key, value, null);
        if(table[newNode.getHash()] != null){
            HashNode temp = table[newNode.getHash()];
            HashNode last = null;
            while (temp != null){
                if(temp.getKey().equals(key)){
                    temp.setValue(value);
                    return;
                }
                last = temp;
                temp = temp.getNext();
            }
            last.setNext(newNode);
        }else{
            table[newNode.getHash()] = newNode;
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值