java查找一个数等于一组数中哪些数字相加的和_java技能树4——HashMap

1.HashMap

HashMap是基于哈希表的Map接口实现。此实现提供所有可选的映射操作,并允许使用null值和null键(除了不同步和允许使用null之外,HashMap类与Hashtable大致相同)。此类不保证映射的顺序,特别是不保证该顺序恒久不变。

值得注意的是HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法sychronizedMap获得安全的HashMap;

Map map = Collections.sychronizedMap(new HashMap());

1.1 hash

数组和向量都可以存储对象,但对象的存储位置是随机的,也就是说对象本身与其存储位置之间没有必然的联系。当要查找一个对象时,只能以某种顺序(如顺序查找或二分查找)与各个元素进行比较,当数组或向量中的元素数量很多时,查找的效率会明显的降低。

一种有效的存储方式,是不与其他元素进行比较,一次存取便能得到所需要的记录。这就需要在对象的存储位置和对象的关键属性(设为k)之间建立一个特定的对应关系(设为f),使每个对象与一个唯一的存储位置相对应。在查找时,只要根据待查对象的关键属性k计算f(k)的值即可。如果此对象在集合中,则必定在存储位置f(k)上,因此不需要与集合中的其他元素进行比较。称这种对应关系f为哈希(hash)方法,按照这种思想建立的表为哈希表。

1.1.1 hash算法

hash算法接受任意长度的二进制输入值,对输入值做换算,最终给出固定长度的二进制输出值。MD5就是比较著名的hash算法。

1.1.1.1 hash算法作用

1.1.1.1.1 信息安全领域

可用作加密算法,如文件校验:通过对文件换算,可以得到文件的"数字指纹",下载的任何副本的“数字指纹”只要和官方的一致,就保证了文件未经篡改,如MD5;

1.1.1.1.2 数据结构领域

hash算法可以用作快速查找,如哈希表。

1.1.2 哈希表

1.1.2.1 常用查找方式

1.1.2.1.1 非哈希查找

主要值得是线性表和树结构。这些结构中,记录的相对位置是随机的,和记录的关键字之间不存在确定关系,因此,在结构中查找时需要进行一系列和关键字的比较。这一类查找方法建立在“比较”的基础上。在顺序查找时,比较的结果为“=”与“≠”2种可能;在折半查找、二叉排序树查找和B-树查找时,比较的结果为“<”“=”“>”3种可能。查找的效率依赖于查找过程中所进行的比较次数。

1.1.2.1.2 哈希表

理想的情况是希望不经过任何比较,一次存取便能得到所查记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的关系,使每个关键字和结构中一个唯一的存储位置相对应。因而在查找时,只要根据这个对应关系找到给定值的像。若结构中存在关键字和相等的记录,则必定在的存储位置上,反之在这个位置上没有记录。由此,不需要比较便可直接取得所查记录。在此,我们称这个对应关系为哈希(Hash)函数 ,按这个思想建立的表为哈希表 。

1.1.2.2 什么是哈希表

1.1.2.2.1 哈希函数特点

哈希函数具有如下的特点:

  • 1.灵活。哈希函数是一个映像,因此哈希函数的设定非常灵活,只要使得任何关键字都是由此所得的哈希函数值落在表长允许的范围之内即可。
  • 2.冲突。对不同的关键字可能得到同一哈希地址,这种现象称为冲突(collision);冲突只能尽量地少,而不能完全避免。因为,哈希函数是从关键字集合到地址集合的映像。而通常关键字集合比较大,它的元素包括所有可能的关键字,而地址集合的元素仅为哈希表中的地址值。因此,在实现哈希表这种数据结构的时候不仅要设定一个“好”的哈希函数,而且要设定一种处理冲突的方法。

1.1.2.2.2 哈希表定义

哈希表:根据设定的Hash函数和处理冲突的方法,将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的映像作为记录在表中的存储位置,这样的表便称为Hash表;哈希表能够实现满足数据的查找方便,同时不占用太多的内容空间,使用方便。

6cbd62da0147fb9fb24186f7b9b89635.png

1.1.2.2.3 哈希表数据存储

如图所示,哈希表是由数组+链表实现,一个长度为16的数组内,每个元素存储的是一个链表的头结点。这些元素通过hash(key)%len,即元素的key的哈希值对数组长度取模得到。如上表,12%16=12,28%16=12,108%16=12,140%16=12。所以12、28、108以及140都存储在数组下标为12的位置.

1.1.2.3 哈希函数

1.1.2.3.1 选用考虑因素

  • hash函数执行时间
  • 关键字长度
  • hash表的大小
  • 关键字的分布情况
  • 记录的查找频率

1.1.2.3.2 常用构造方法

1.1.2.3.2.1 直接寻址法

取k或者k的某个线性函数为hash地址。

特点:由于直接地址法相当于有多少个关键字就必须有多少个相应地址去对应,所以不会产生冲突,也正因为此,所以实际中很少使用这种构造方法。

1.1.2.3.2.2 数字分析法

首先分析待存的一组关键字,比如是一个班级学生的出生年月日,我们发现他们的出生年 大体相同,那么我们肯定不能用他们的年来作为存储地址,这样出现冲突的几率很大;但是,我们发现月日的具体数字差别很大,如果我们用月日来作为Hash地址,则会明显降低冲突几率。因此,数字分析法就是找出关键字的规律,尽可能用差异数据来构造Hash地址 ;

特点:需要提前知道所有可能的关键字,才能分析运用此种方法,所以不太常用。

1.1.2.3.2.3 平方取中法

先求出关键字的平方值,然后按需要取平方值的中间几位作为哈希地址。这是因为:平方后中间几位和关键字中每一位都相关,故不同关键字会以较高的概率产生不同的哈希地址。

特点:常用,英文单词以及某些关键字使用该种方法。

1.1.2.3.2.4 折叠法

将关键字分割成位数相同的几部分(最后一部分位数可以不同),然后取这几部分的叠加和(去除进位)作为散列地址。数位叠加可以有移位叠加和间界叠加两种方法。移位叠加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加。

1.1.2.3.2.5 随机数法

选择一个随机函数,取关键字的随机函数值作为Hash地址,通常用于关键字长度不同的场合。即

特点:通常,关键字长度不相等时,采用此法构建Hash函数 较为合适。

1.1.2.3.2.6 除留取余法

取关键字被某个不大于Hash表 长m 的数p 除后所得的余数为Hash地址 。

特点:这是最简单也是最常用的Hash函数构造方法。可以直接取模,也可以在平法法、折叠法之后再取模。

值得注意的是,在使用除留取余法时,对p的选择很重要,如果p选的不好会容易产生同义词 。由经验得知:p最好选择不大于表长m的一个质数、或者不包含小于20的质因数的合数。

1.1.2.4 处理冲突

冲突是指由关键字得到的哈希地址为的位置上已存有记录,则“处理冲突”就是为该关键字的记录找到另一个“空”的哈希地址。在处理冲突的过程中可能得到一个地址序列。即在处理哈希地址的冲突时,若得到的另一个哈希地址仍然发生冲突,则再求下一个地址,若仍然冲突,再求,依次类推,直至不发生冲突为止,则为记录在表中的地址。(需要注意此定义不太适合链地址法)

1.1.2.4.1 开放定址法

线性探测再散列,二次探测再散列,伪随机探测再散列

1.1.2.4.2 再哈希法

1.1.2.4.3 链地址法

java中hashmap解决办法就是采用链地址法。

1.1.2.4.4 建立一个公共溢出区

1.2 HashMap数据结构

1.2.1 数组和链表特点

1.2.1.1 数组

数组存储区间是连续的,占用内存严重,故空间复杂度大,但是数组的二分查找时间复杂度小,为O(1),数组的特点是:寻址容易,插入和删除困难。

1.2.1.2 链表

链表存储区间离散,占用内存比较松散,故空间复杂度小,但时间复杂度大为O(N)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值