java-HashMap分析

(一)哈希算法

哈希算法,将原始数据通过散列函数映射为较短的固定长度的二进制值,简称哈希值。

hash算法有两个基本特点:可重复和不可逆。理论上计算出的哈希值是可重复的,但好的散列函数基本不会出现这种情况。不可逆指,知道哈希值无法推算出原始数据。

哈希算法一般用于快速查找(如HashMap)和加密算法(如MD5)。


(二)java中的hashcode

java中对象基类Object有hashcode方法,native调用默认返回对象内存地址,hashcode返回不定长的10进制数。

Java对于eqauls方法和hashCode方法是这样规定的:1、如果两个对象相同(equal),那么它们的hashCode值一定要相同;2、如果两个对象的hashCode相同,它们并不一定相同。 

hashcode可以重写,String重写了hashcode。

public int hashCode() {
	int h = hash;
        int len = count;
	if (h == 0 && len > 0) {
	    int off = offset;
	    char val[] = value;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] 

使用 int 算法,这里 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希码为 0。)


(三)hashmap源码分析

数据格式:数组和链表结合的拉链法哈希表。


    /**
     *整个HashMap的基本数据结构
     */
    transient HashMapEntry<K, V>[] table;
    
    static class HashMapEntry<K, V> implements Entry<K, V> {
        //put(key,value)中的key
        final K key;
        //put(key,value)中的value
        V value;
        //经过哈希映射函数计算出的hash值
        final int hash;
        //指向下一个HashMapEntry
        HashMapEntry<K, V> next;

        HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) {
            this.key = key;
            this.value = value;
            this.hash = hash;
            this.next = next;
        }
        ....
    }
public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        //防止质量较差的哈希函数带来过多的冲突(碰撞)问题,进一步使用映射函数生成值
        int hash = hash(key.hashCode());
        //计算出该hash属于哪个数组位置坐标
        int i = indexFor(hash, table.length);
        //检测该key是否已存在于数组为i的链表中
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            //hash相同,key不一定相同
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        //从头部插入该HashMapEntry对象
        addEntry(hash, key, value, i);
        return null;
    }

(四)HashMap和HashTable的区别

1.继承不同

Hashtable extends Dictionary
HashMap  extends AbstractMap
2.同步

HashMap是非同步的,HashTable是同步的

3.插入值

HashMap键值允许为null,HashTable不允许

HashMap通过get方法获取到null不代表不存在该key,必须用containsKey()方法来判断。

HashMap<String, String> hashMap = new HashMap<String, String>();
        hashMap.put("1", null);
        System.out.println(hashMap.get("1"));//null
        System.out.println(hashMap.get("2"));//null




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值