`
gogoalong
  • 浏览: 49123 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

Hash结构

阅读更多
关于HashMap  在http://www.iteye.com/topic/754887这篇文章中有做比较好的讲解
下面是我在一些点上自己的看法。
我们会经常使用HashMap类来进行存储数据,HashMap<K k,V v>map = new HashMap<K k,V v>();对于Map我们经常使用的也就是put(k,v);remove();search();这三个方法,我们添加数据到HashMap结构中,只觉得它用起来还不错,但它不错在哪?
   一,Hash结构有什么优势?
   我们知道数组是便于查找,因为它的下标,而链表便于添加和删除,(修改地址指向),但是对于很多个数,比如上亿,如果我们用数组来存储这么多数,如果我们要删除其中的一个元素,我们将会移动N个,同样用在链表查找的时候也很费劲。Hash结构中的拉链式(书上的名词)是结合数组和链表的一种存储结构(还有一种叫开放定址法)通过数组的下标设成Index索引,把结点挂在数组Entry[]上,Hash结构的优势在于它既便于查找,也在删除和添加上较快。
   二,我对HashMap的浅析
   1)
 static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;//关键字
        V value;//存储的数据数值
        Entry<K,V> next;//在解决冲突的时候,创建链表的时候使用,表示下一个结点。
        final int hash;
  HashMap用Entry类来存储数据,HashMap中数组的默认长度是16
  2)看到上面的hash没,我吧下面段编码放在一起,这样更便于我们的理解
         static int hash(int h) {
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
        }

          
int hash = hash(k.hashCode());
	int i = indexFor(hash, table.length);

  
static int indexFor(int h, int length) {
        return h & (length-1);
    }

hash值是通过Key的hashCode()(hash编码)得来的,i是要存入数据的索引地址,HashMap中的索引是用与运算得到,我们也可以用别的方法,比方说取模 % 。为什么要把hash值和(length+1)做与运算,而不是用(length)呢!这是官方通过实验调查得出结论,官方上说 奇数比偶数要好,理论研究表明:length-1取不大于数组长度的素数效果最好。
  3)Hash冲突,解决方法
   上面讲到了Hash冲突,那么我们会在什么时候遇到Hash冲突呢,打个比方:我们现在有初始状态下的数组,数组的长度是16,当我们添加20元素,通过取模1和17的索引就相同了,这就叫Hash冲突。
   解决Hash冲突 , 上面讲过一点,我们通过子添加结点,把冲突的元素挂在链表上Entry<K,V> next 
下面是我的添加结点的方法
Entry<k,v>node = new node<k,v>();
index=Indexfo(hash,table.length);
node.next=table[index].next;
table[index].next =node;

冲突是一个问题,但还有另一个问题,如果添加的元素都是具有同一个索引,那么我们就会把他一直的往链表上挂,那么我们得到的就会非常的偏向于链表,我们的Hash表就没有什么优势存在,所以我们需要控制每个链表的长度,也就是设置一个阀值,用来使得我们的Hash表存储的数据分布尽量的均匀。
4)如何使得分布均匀
我们通过给链表加一个长度计数变量,在添加元素的时候进行判断,如果链表的长度超过我们设定的阀值,那么我们就重新设置我们的数组的长度

在HashMap中有这么一个方法
resize(int newCapacity){...
transfer(newTable);//转移原数组的元素到新的数组
...}

我们在调用resize(n)是,这个n可以设定为原数组的2倍或其他
在上面我们看到了transfer(newTable);这个方法这个方法是用来进行转移的
我们知道数组在内存中的开辟地址的,他的大小我们是不改变的,所以我们要用到transfer(newTable);这个方法,这个方法有必要记住,在以后我们使用的时候随手捏来
void transfer(Entry[] newTable) {
        Entry[] src = table;
        int newCapacity = newTable.length;
        for (int j = 0; j < src.length; j++) {
            Entry<K,V> e = src[j];
            if (e != null) {
                src[j] = null;
                do {
                    Entry<K,V> next = e.next;
                    int i = indexFor(e.hash, newCapacity);
                    e.next = newTable[i];
                    newTable[i] = e;
                    e = next;
                } while (e != null);
            }
        }
    }

这个方法是扩展数组的长度
5) 在HashMap中有一个变量  loadFactor  这个叫做 比例因子
这个的用法是在我们设置阀值的时候用到
HashMap中
threshold = (int)(newCapacity * loadFactor);
这个就是设置阀值   在HashMap中loadFactor  的取值是0.75,官方给出了一个取值范围0.6~0.9  这样的效果是比较好的,到底好在哪里?我测试不出,如果你们有兴趣,可以自己想个方法测试一下,前提,你的电脑性能要好。
    到此一个Hash表的结构基本可以了,有不足的地方希望大家能够指出。文章应该写些什么,也希望大家给意见。
分享到:
评论

相关推荐

    基于Hash结构的逆向最大匹配分词算法的改进_丁振国1

    本文主要探讨了基于Hash结构的逆向最大匹配分词算法的改进,旨在提高分词速度和准确性,减少歧义。 1. 分词算法概述 - 最小匹配算法:这是一种早期的分词方法,从字符串左侧开始,每次取固定长度的字段与词典对比...

    hash表实现举例 hash结构中带超时链表的实现

    1. hash key值计算,key的比较,内存分配,可以通过实现模板类重新定制 2. 实现按插入时间的先后,通过有序链表访问节点。用于按照时间先后,快速遍历(删除)超时节点。 3. hash 实现快速存取, 链表快速实现...

    yew:提供对象访问,如对 Hash 结构的接口

    Yew 允许像遍历对象树一样遍历 Hash 结构。 用法 鉴于位于config/env.yml的以下 yml 文件: orientdb : url : ' remote:localhost/db ' user : admin pass : secret testing : frameworks : minitest : true ...

    hash表C语言实现

    哈希表(Hash Table)是一种数据结构,它通过计算一个关联数组中的索引来确定一个元素的存储位置,这种计算过程通常称为哈希函数。在C语言中实现哈希表,可以提供快速的数据查找、插入和删除操作,尤其适用于大数据...

    UMAT_Hashin3D_hashin

    总之,“UMAT_Hashin3D_hashin”是一个基于Hashin破坏准则的三维复合材料损伤分析工具,其核心在于用编程方式实现材料损伤的动态模拟,以帮助工程师理解和预测复杂复合材料结构在不同工况下的行为。

    3d.zip_3维hashin准则_Hashin 3D_hashin_失效准则_层合板 hashin

    6. **计算方法**:在实际应用中,3D Hashin准则通常与有限元分析结合,通过对材料的微结构进行模拟,计算每个单元的失效状态,并确定整个结构的整体失效。 7. **应用范围**:3D Hashin准则广泛应用于航空航天、汽车...

    HASHIN.rar_ABAQUS_Hashin失效准则 abaqus_abaqus hashin_abaqus 三维Hashi

    在实际应用中,使用三维实体单元和Hashin失效准则可以对复杂结构进行详细分析,例如评估飞机机翼、复合材料部件或其他工程结构在多向应力下的稳定性。用户子程序允许用户自定义材料模型,如Hashin失效准则,以适应...

    uthash开源的hash函数实现

    UTHASH 是一个开源的 C 语言库,提供了一种简单且高效的哈希表实现,用于在 C 代码中快速查找和管理数据结构。这个库的主要功能是提供一个宏定义的集合,可以方便地将结构体转化为哈希表,进而进行添加、删除、查找...

    Redis大Key解决方案.docx

    - 如果对象每次只需要存取部分数据,同样可以将其拆分成多个键值对,或者存储为一个Hash结构,其中每个Field代表对象的一个具体属性。这样可以通过`HGET`或`HMGET`命令获取部分Value,使用`HSET`或`HMSET`更新部分...

    hashin-strain-3d_hashin_三维hashin_三维hashin失效_失效准则_3D—Hashin_

    在实际工程应用中,三维Hashin失效准则通常与有限元分析结合,对复杂结构的复合材料进行模拟。这需要将失效准则嵌入到求解器中,通过迭代求解应力和应变场,判断材料在各个位置是否达到失效状态。这种方法既考虑了...

    C开源hash代码uthash

    该套开源代码采用宏的方式实现hash函数的相关功能,支持C语言的任意数据结构最为key值,甚至可以采用多个值作为key,无论是自定义的struct还是基本数据类型,需要注意的是不同类型的key其操作接口方式略有不通。...

    RedisKing publish.zip

    RedisKing是一款专为Redis数据库设计的管理工具,它提供了便捷的操作界面,允许用户对Redis中的数据进行读写操作,尤其适用于处理hash结构和普通的key-value结构。通过使用RedisKing,用户能够更直观地管理和维护...

    海量非结构化数据管理方案.docx

    - Redis的优化包括选择合适的数据结构(如使用Hash结构代替set或list操作)、合理设计key过期时间、配置maxmemory和maxmemory-policy、使用命令合并和管道命令减少网络开销、优化命令复杂度以及合理设置maxclients。...

    海量非结构化数据的高效管理.docx

    - Redis的优化建议包括:根据需求选择合适的数据结构,如使用Hash结构代替Set操作;合理设定key的过期时间;配置maxmemory和maxmemory-policy以避免性能下降;设计高效的命令使用,如命令合并和管道命令;并适当设置...

    HASHIN_hashin子程序_imagehashing_Fortran_ABAQUSvumat_

    标题中的"HASHIN_hashin子程序_imagehashing_Fortran_ABAQUSvumat_" 提到了几个关键概念:HASHIN子程序、imagehashing、Fortran编程语言以及ABAQUS的VUMAT(用户材料子程序)。这些元素共同构成了一个在ABAQUS环境下...

    hashin失效vumat,hashin失效准则介绍,Fortran

    通过阅读和理解这个文件,工程师们可以学习如何将Hashin失效准则应用到实际的工程计算中,从而更准确地模拟和预测复合材料结构的性能和寿命。 在实际应用中,Hashin失效准则与VUMAT的结合可以帮助解决许多关键问题...

    hashin失效vumat_hashin破坏准则_vumatfailure_vumathashin失效_hashin_vumat

    在VUMAT中集成Hashin失效准则,可以精确模拟复合材料在不同载荷下的失效过程,例如在土木工程中预测结构在地震或风荷载下的响应,或者在航空航天领域分析飞行器的耐久性。 在“hashinʧ Чvumat.txt”这个文件中,...

    Redis 实践

    通过将图片ID分段,并使用前四位作为Hash结构的key,Instagram成功地将内存消耗降至每1,000,000条记录仅需16MB,总内存使用量降低至5GB,远低于最初的21GB,充分满足了业务需求。 #### 进一步的优化探索 在初步的...

Global site tag (gtag.js) - Google Analytics