`

HashMap简析之-HashCode冲突的解决

    博客分类:
  • java
阅读更多

总述:通过一定的算法,将key的hashcode转换成数组的index;将key,value,hash等信息保存在数组对应的index位置上.

 

问题:

1.某些key的hashcode相同

2.hashcode不同,但一定算法后映射到数组的index相同

这个就是常说的hashcode冲突问题.

 

1.HashMap涉及的数据结构

   Entry[] ;

   //Entry数组:存储HashMap元素的地方.

   //Entry

   //1.封装了key;value;

   //2.本身是一个单向链表;包含hash值;next;指针;

  

 static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        final int hash;
        Entry<K,V> next;

        /**
         * Create new entry.
         */
        Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }

         ....
}

 

  

 

2.存储的过程:

 

通过hashcode得到index后.存储的不仅仅是该元素的key,value,hash.还有指向下一个Entry的引用.如果出现了hashcode冲突问题.则新建一个Entry;将该Entry的nex指针指向已存在的Entry.

  

public V put(K key, V value) {
        K k = maskNull(key);
        int hash = hash(k);                    //算hash
        int i = indexFor(hash, table.length);  //取对应的index
        //该index对应的Entry可能不是一个Entry,而是一个Entry链.
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            if (e.hash == hash && eq(k, e.key)) { //已存在,则更新值.
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, k, value, i); //该位置还空;或者位置不空,但已有Entry(hashcode冲突)
        return null;
    }

 

   void addEntry(int hash, K key, V value, int bucketIndex) {
            //取到当前位置上的Entry,可能是null
            Entry<K,V> e = table[bucketIndex];
            //创建新Entry,next指向已存在的
            table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        
            if (size++ >= threshold)
                     resize(2 * table.length);//扩容.
    }

 

 

 

 

3.取值的过程

 

还是hash-index-Entry的过程.不是直接return该index上Entry;而要检查Entry链上真正对应的那个

    public V get(Object key) {
        Object k = maskNull(key);
        int hash = hash(k); //取hash
        int i = indexFor(hash, table.length);//取index
       
        //取回来的是一个Entry链
         Entry<K,V> e = table[i]; 
        //遍历
         while (true) {
            if (e == null)
                return null;
            if (e.hash == hash && eq(k, e.key)) //真正要get的那个
                return e.value;
            e = e.next; //指针后移到下一个Entry
        }
    }

 

算个复习吧.没看过的看看.笔试面试很常见.

2
0
分享到:
评论
1 楼 步青龙 2012-04-12  
好文章 赞一个

相关推荐

    HashMap的用法---马克-to-win java视频

    HashMap的用法---马克-to-win java视频的详细描述与介绍

    HashMap源码分析-思维导图.xmind

    hashmap的原理啊思想。

    20-集合框架020-HashMap-1080P 高清-AVC20

    在这个主题中,我们将深入探讨HashMap类,它是Java集合框架中的一个关键组件,特别是在标题“20-集合框架020-HashMap-1080P 高清-AVC20”和描述中所提到的内容。 HashMap是Java.util包中的一个类,它实现了Map接口...

    hashmap-thread-test:测试 Java HashMap 是否是线程安全的

    本项目“hashmap-thread-test”显然是为了测试和展示这一特性。 ### Java HashMap 的特性 1. **非线程安全**:`HashMap`不是线程安全的,因为它没有内置的同步机制来保护并发访问。当多个线程同时修改`HashMap`时...

    JAVA之hashmap源码分析-Mobile-Dev-Analysis:android或java的分析

    JAVA之hashmap源码分析 Mobile-Dev-Analysis Analysis of android or java 红岩网校工作站移动开发部学员分组学习 为了让大家学的更加坚固,采取小组学习的方式帮助大家学习,同时在学习研究的过程中需要不断的做...

    java代码-使用java解决手写hashMap的源代码

    java代码-使用java解决手写hashMap的源代码 ——学习参考资料:仅用于个人学习使用!

    易语言HashMap类源码-易语言

    2. **冲突解决**:当两个或更多键的哈希值相同时,HashMap需要一种策略来处理这种情况。常见的方法是使用链表链接所有冲突的键值对,或者采用二次探测、双哈希等方法来寻找其他空位。 3. **动态扩容**:随着键值对...

    c_hashmap-master_hashmap.keys_C-C++_establishgkb_TheKeys_

    《C语言实现的哈希映射——c_hashmap-master中的keys操作详解》 在计算机科学领域,哈希映射(Hash Map)是一种高效的数据结构,它通过特定的哈希函数将键(Key)映射到数组的索引位置,从而实现快速的查找、插入和...

    java7hashmap源码-Excellent-Blog-share:欢迎分享优秀博客

    hashmap源码 Excellent-Blog-share Welcome to share excellent blogs . 当你的能力还驾驭不了你的目标时,就应该沉下心来历练 当你的才华还撑不起你的野心时,那你就应该静下心来学习 #目录 ###附录 java系列 java8...

    hashmap的get流程 - 副本.md

    hashmap的get流程 - 副本

    深入 HashCode 方法~

    - `Hashtable` 和 `HashMap` 为了提高性能,会尽量避免哈希冲突的发生,即多个对象具有相同的 `HashCode`。 - 为了减少冲突,可以通过优化 `HashCode` 的计算方法,使不同的对象尽可能获得不同的 `HashCode` 值。 ...

    自定义map实现java的hashmap

    通过以上分析,我们可以了解到实现一个自定义的HashMap涉及许多细节和技巧,包括哈希函数的设计、冲突解决策略的选择、以及性能优化等。在实际编程中,理解这些概念有助于我们更好地使用和定制HashMap,满足特定需求...

    HashMap-hash原理

    `HashMap`的内部实现会调用键对象的`hashCode()`方法,然后对其进行一定的转换操作,以便更好地分布数据并减少冲突。 #### 三、高位扩展与低位扩散 在`HashMap`中,对于计算得到的哈希码,官方文档提到一个非常...

    HashMap源码分析系列-第四弹:HashMap多线程解决方案.docx

    ### HashMap多线程解决方案 #### 一、引言 在多线程环境下,Java的`HashMap`类在处理并发操作时容易出现线程安全问题。本文档深入探讨了`HashMap`在多线程环境中可能遇到的安全问题,并提出了一系列可行的解决方案...

    一个delphi的hashmap源代码

    - 分析`Hashes.pas`文件可以深入了解这些哈希表的实现细节,包括它们的内部结构、冲突解决策略和性能优化技巧。 - 对源代码的研究可以帮助开发者学习如何在Delphi中高效地实现自定义的哈希表。 总之,这个Delphi...

    Java 实例 - HashMap遍历源代码-详细教程.zip

    在Java编程语言中,HashMap是集合框架中一个重要的类,用于存储键值对的数据结构。这个实例教程将深入解析HashMap的遍历方法及其源代码,帮助开发者更好地理解和使用HashMap。以下是对这个主题的详细讲解: 1. **...

    面试必考之HashMap源码分析与实现

    当两个键的哈希值相同,导致冲突时,HashMap使用链地址法来解决,即将冲突的键值对链接成一个链表。 3. **哈希冲突处理** 在HashMap中,如果两个键的哈希值相同但并不相等,它们会在同一个桶(数组索引位置)形成...

    简单的key value hashmap

    如果有,就需要进行冲突解决。Java的HashMap采用链地址法处理冲突,即将所有哈希冲突的键值对挂在同一个桶的链表上。 3. 查找键值对时,首先计算键的哈希码,找到对应的桶,然后遍历链表,使用`equals()`方法比较键...

Global site tag (gtag.js) - Google Analytics