`
daqing15
  • 浏览: 40886 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

HashMap来自互联网的小结

阅读更多

 

        HashMap毋庸置疑,一定是我们这些Java程序员第一大实用工具,因为其在存储数据方面,有些“无所不能”哈,而且效率与性能都合我们的意。也是因为这个HashMap在应用程序中应用过多,所以网上出现了针对HashMap的各种剖析,呵呵,鄙人也看过其源码!了解过其具体的实现,所以此时有意来总结一下在网路上的一些对HashMap的各种解析。

HashMap中的Hash算法
      HashMap使用了散列表,而散列表中要关注的问题是,如何尽可能地减少散列值的冲突,通常有两种方法,链表法和开放地址法。(嗯!数据结构的书上会有更详尽的解释)
【链表法】将相同hash值的对象组织成为一个链表放在hash值对应的槽位;
【开放地址法】通过一个探索算法,当某个槽位已经被占据的情况下继续查找下一个可以被使用的槽位。
【负载因子和容量】:在JDK中,一个HashMap的实际容量就为 【因子】*【容量】,
   JDK提供的默认值为:16*   0.75=12;
【负载因子】,负载因子a = 散列表的实际元素数目(n)/散列表的容量(m)
  在此,负载因子衡量的是一个散列表的空间使用程度,负载因子越大表示散列表的装填程度越高,反之越少。
  在JDK中,HashMap采用的是链表法的方式,而链表为单向链表,在删除过程中要自己维护previous节点
【SourceCode】
for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
}

HashMap的数据结构:数组和链表的结合体(被称为“链表散列)。如下图所示:

 


从这张图,可得到一些有用信息,HashMap中get方法的高效率,因为在HashMap中,数据时保存在数组上,从而就利用了数据的天生优点——可直接通过索引定位元素的位置。当然,在HashMap中的实现中,这个过程并不是像平常那样直接使用,看看HashMap中get方法实现吧
public V get(Object key) {
        if (key == null)
            return getForNullKey();
        int hash = hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        return null;
    }
在方法体中,真正定位元素的存放位置也是通过hash值的。
每个元素上的链表存放,利用put方法塞元素时,先根据key的hash值得到这个元素在数组上的位置(下标),然后就可以把这个元素放在对应的位置上,若是,这个位置上已有其他元素,那么就会在同一个位置上将元素以链表的形式存放。新的加入放在链头,最先加入的放在链尾。HashMap 采用一种所谓的“Hash 算法”来决定每个元素的存储位置

HashMap中的resize的实现
当hashmap中的元素越来越多的时候,碰撞的几率也就越来越高(因为数组的长度是固定的),所以为了提高查询的效率,就要对hashmap的数组进行扩容。在这个过程中,最消耗性能的关键点出现:原数组中的数据必须重新计算在新数组中的位置,并放进去。
这个问题,就要我们在开发过程中,要预知一下HashMap的可能大小,再给它初始化为离这个大小的接近2的整数次幂次方吧!但,这个并不是最完美的解决之道。看某位仁兄的:
比如说,我们有1000个元素new HashMap(1000), 但是理论上来讲new HashMap( 1024)更合适,不过,即使是1000,hashmap也自动会将其设置为1024。 但是new HashMap(1024)还不是更合适的,因为0.75*1000 < 1000, 也就是说为了让0.75 * size > 1000, 我们必须这样new HashMap(2048)才最合适,既考虑了&的问题,也避免了resize的问题。

HashMap的有效使用
如果你想有效的使用HashMap,你就必须重写在其的HashCode()!
覆盖hashCode方法,使相同内容的对象来说它们的hashcode也就相同了(这样就能迅速的定位某个元素的位置)
覆盖equals方法,为了在HashMap中判断两个key是否相等时使结果有意义。
在改写equals方法的时候,需要满足以下三点:
(1) 自反性:就是说a.equals(a)必须为true。
(2) 对称性:就是说a.equals(b)=true的话,b.equals(a)也必须为true。
(3) 传递性:就是说a.equals(b)=true,并且b.equals(c)=true的话,a.equals(c)也必须为true。


两条重写建议牢记的原则:
"不为一原则",不必对每个不同的对象都产生一个唯一的hashcode,只要你的HashCode方法使get()能够得到put()放进去的内容就可以了。
"分散原则",生成hashcode的算法尽量使hashcode的值分散一些,不要很多hashcode都集中在一个范围内,这样有利于提高HashMap的性能。

【参考的原文章出处,非常感谢大伙们的好文】
http://www.iteye.com/topic/368087
http://www.iteye.com/topic/539465

  • 大小: 62.9 KB
0
0
分享到:
评论

相关推荐

    hashmap面试题_hashmap_

    《HashMap面试题详解》 HashMap作为Java集合框架中的重要成员,是面试中常见的知识点,尤其在数据结构与算法、并发编程以及JVM内存管理等领域,HashMap的深入理解至关重要。本篇将围绕HashMap的相关面试题,从基础...

    HashMap介绍和使用

    ### HashMap介绍和使用详解 #### 一、HashMap的数据结构 HashMap是Java集合框架的一个重要组成部分,它实现了Map接口,能够存储键值对映射。在Java编程语言中,最基本的数据结构有两种:数组和引用(模拟指针)。...

    hashmap实现原理

    哈希映射(HashMap)是Java编程语言中广泛使用的数据结构之一,主要提供键值对的存储和查找功能。HashMap的实现基于哈希表的概念,它通过计算对象的哈希码来快速定位数据,从而实现了O(1)的平均时间复杂度。在深入...

    Java HashMap类详解

    Java HashMap 类详解 本资源详细介绍了 Java 中的 ...7. 小结 本资源详细介绍了 Java 中的 HashMap 类,包括其实现机制、Hash 存储机制、集合存储机制等方面的知识点,为大家提供了一个详细的 Java HashMap 类详解。

    HashMap的数据结构

    HashMap是Java编程语言中一个非常重要的数据结构,它属于集合框架的一部分,主要用于存储键值对(Key-Value)数据。HashMap在内部实现上基于哈希表,也称为散列表,它提供了一种快速查找、插入和删除数据的方法,...

    HashMap之resize()方法源码解读.docx

    HashMap之resize()方法源码解读 HashMap的resize()方法是HashMap中最核心的方法之一,该方法负责扩容HashMap的容量,以便存储更多的键值对。下面我们将对HashMap的resize()方法进行源码解读,了解其扩容机制和原理...

    HASHMAP排序功能描述

    HashMap是Java编程语言中常用的集合类之一,它属于哈希表数据结构,提供key-value的存储方式,并且具有快速查询的特性。然而,HashMap本身并不保证元素的顺序,特别是当涉及到遍历或输出HashMap的内容时,顺序可能会...

    HashMap和HashTable的区别和不同

    ### HashMap与HashTable的区别详解 #### 引言 在Java编程中,`HashMap`与`HashTable`作为两种常用的数据结构,经常被用来存储键值对数据。尽管它们在功能上相似,但在实现细节、性能表现以及使用场景方面存在显著...

    hashmap 实例

    《HashMap 实例解析与关联数据结构对比》 HashMap 是 Java 中常用的一种数据结构,属于 Java.util 包下的类,它是基于哈希表实现的。在本文中,我们将深入理解 HashMap 的实例及其工作原理,并与其他数据结构如 ...

    HashMap总结

    HashMap 总结 HashMap 是 Java 中的一种常用的数据结构,用于存储键值对(Key-Value)数据。下面是 HashMap 的一些特性和使用方法总结。 键(Key)的特性 1. 键可以为 null:HashMap 中的键可以为 null,这意味着...

    HashMap类.rar

    HashMap类在Java编程语言中是集合框架的一部分,它是一个基于哈希表的Map接口实现。HashMap提供了快速的插入、删除和查找操作,平均时间复杂度为O(1)。在这个压缩包“HashMap类.rar”中,包含的是易语言版本的...

    HashMap存放.doc

    HashMap存放.doc

    基于JavaScript的HashMap实现

    在JavaScript中,HashMap是一种常用的键值对存储结构,它提供了快速的插入、删除和查找操作。JavaScript本身并不直接支持HashMap,但我们可以利用对象(Object)的特性来模拟HashMap的实现。这篇博客“基于...

    hashMap和hashTable的区别

    ### hashMap和hashTable的区别 #### 一、简介与基本概念 `HashMap` 和 `HashTable` 都是 Java 集合框架中非常重要的数据结构,它们都实现了 `Map` 接口,用于存储键值对。尽管它们在功能上有很多相似之处,但在...

    HashMap与HashTable区别

    ### HashMap与HashTable的区别 在Java编程语言中,`HashMap`和`HashTable`是两种非常重要的数据结构,它们都实现了`Map`接口,并提供了键值对的存储方式。这两种数据结构虽然相似,但在实现细节和使用场景上存在...

    HashMap排序

    ### HashMap排序方法详解 在Java开发中,`HashMap`是一种非常常见的数据结构,它通过键值对的形式存储数据。然而,由于`HashMap`是基于哈希表实现的,所以它并不能保证元素的顺序。这就意味着如果需要按照某种特定...

    Java中HashMap详解(通俗易懂).doc

    Java中的HashMap是一个非常重要的数据结构,它实现了Map接口,提供了键值对的高效存储和访问。HashMap基于哈希表(也称为散列表)原理工作,它允许用户通过键(Key)快速查找对应的值(Value)。在HashMap中,键和值...

    HASHMAP缓存.txt

    在深入探讨《HASHMAP缓存.txt》所提及的知识点前,我们先来解析一下文档的标题、描述和部分内容,以确保我们对所讨论的主题有全面的理解。标题“HASHMAP缓存.txt”暗示了文档主要关注的是Java编程语言中HashMap作为...

    枚举 HashMap

    标题"枚举 HashMap"所指的就是用HashMap来实现类似枚举的特性。 HashMap是一种基于哈希表的Map接口实现,它提供了快速的插入、查找和删除操作,时间复杂度通常为O(1)。通过将枚举值作为键(Key),相关属性或行为...

    java HashMap原理分析

    Java HashMap原理分析 Java HashMap是一种基于哈希表的数据结构,它的存储原理是通过将Key-Value对存储在一个数组中,每个数组元素是一个链表,链表中的每个元素是一个Entry对象,Entry对象包含了Key、Value和指向...

Global site tag (gtag.js) - Google Analytics