首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么AND(&)运算符在哈希表中计算最终索引为什么不使用模(%)运算符,即hashValue & ()

在哈希表中,使用AND(&)运算符计算最终索引而不使用模(%)运算符的原因是为了提高计算效率和减少计算复杂度。

哈希表是一种常用的数据结构,用于存储键值对。在哈希表中,键通过哈希函数转换为哈希值,然后根据哈希值计算出对应的索引位置,将值存储在该位置上。当需要查找或插入键值对时,通过哈希函数计算出哈希值,然后根据哈希值计算出索引位置,从而快速定位到对应的位置。

使用AND(&)运算符计算最终索引的原理是,哈希表的大小通常是2的幂次方,例如16、32、64等。这样,哈希值与哈希表大小进行AND运算,可以保证最终索引的范围在哈希表的大小范围内,即0到哈希表大小-1之间。这种方式可以通过位运算实现,效率较高。

相比之下,使用模(%)运算符计算最终索引的方式需要进行除法运算,除法运算相对于位运算来说,计算复杂度较高,效率较低。而且,哈希表的大小通常是2的幂次方,这样使用模(%)运算符计算最终索引时,取模的结果与哈希表大小-1相等,即hashValue % (哈希表大小-1)等价于hashValue & (哈希表大小-1)。因此,为了提高计算效率,直接使用AND(&)运算符计算最终索引是更好的选择。

总结起来,使用AND(&)运算符计算最终索引可以提高计算效率和减少计算复杂度,而不使用模(%)运算符是因为哈希表的大小通常是2的幂次方,并且取模的结果与使用AND运算的结果相等。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

HashMap 底层原理

通过 hash 函数计算得到,HashCode 就是 hash 中有对应的位置HashCode 的存在主要是为了查找的快捷性,HashCode 是用来散列存储结构确定对象的存储地址的Java...并不是直接使用的方式控制 1-15 之间,是采用位运算的方式,位运算的效率要高于取,位运算效率最高,取效率最差。‍...取运算块,能保证索引值肯定在 capacity ,不会超出数组的长度,(n - 1) & hash,当 n 为 2 次幂时,会满足一个公式:(n - 1) & hash = hash % n。...源码计算数组位置。图片图片取出 key 的 HashCode,进行一些异常和与操作,目的让得到的值更加 hash,减少 hash 碰撞。...图片在源码采用按位与的形式计算得出在数组当中的位置, HashMap 并不是直接使用的方式控制 1-15 之间,是采用位运算的方式,位运算的效率要高于取,位运算效率最高,取效率最差,图片图片

16120

《Java从入门到失业》第三章:基础语法及基本程序结构(3.7):运算符(基本算数运算符、原码、反码、补码)

3.7.1基本算数运算符        Java,采用+、-、*、/、%来表示加、减、乘、除、取余(取),这种运算小学就学过,无需多讲,列表举例如下: 运算 算式 结果(假设a=15,b=10)...那么又为什么要把减法转换为加法呢?我们学习过计算机组成,知道CPU只有加法寄存器,因为计算处理加法比较简单,如果要直接处理减法,需要增加逻辑部件,而且处理减法有借位问题很麻烦。...计算机也可以看成一个计量机器,因为计算机的字长是定长的,存储和处理的位数是有限的,因此它也有一个计量范围,都存在一个“”。对于字长3位的机器来说,计数范围是0-7,是8。...聪明的你一定可以想到,补数都是成对的,我们把成对的补数的一半规定为负数是不是就可以了?例如a-1=a+(-1)=a+7,假如我们规定7的二进制111代-1,那么计算的时候就没有减法了。...而且这样一来我们还惊奇的发现: 所有的正数最高位都是0,负数最高位都是1 所有负数的二进制都是它所对应的绝对值的二进制按位取反后+1,就是补码 到此为止,我们就搞清楚了为什么计算要用补码来表示负数了

55720

Presto统计信息

Available Statistics Presto提供以下统计信息: 对于: 行数:table layout的总行数 对于的每一列: 数据大小:需要读取的数据大小 空值分数:空值的分数 不重复值计数...:不重复值的数量 低值:列的最小值 高值:列的最大值 可用于特定查询的统计信息集取决于所使用的连接器,并且还可能因甚至table layout而异。...,将基于查询中表的统计信息来计算与计划的每个节点关联的成本。...计算出的成本将作为EXPLAIN语句输出的一部分进行打印。 成本信息以{rows: XX (XX), cpu: XX, memory: XX, network: XX}的格式显示计划树。...SINGLE 片段单个节点上执行. HASH 片段固定数量的节点上执行,使用哈希函数分配输入数据. ROUND_ROBIN 片段固定数量的节点上执行,输入数据以round-robin方式分布.

2.5K30

SQL 教程:如何编写更佳的查询

这对一门20世纪70年代初就被开发出来的语言来说还不赖,对吧? 那么到底SQL为什么被这样频繁地使用呢?为什么它即使已经存在了这么长时间还不死呢?...LIKE 运算符 查询中使用LIKE运算符时,如果模式以%或_开头,就不会用到索引。它会阻止数据库使用索引(如果有索引的话)。...提示:在这里也要记住,尽管OR以及下面几节中提到的其他运算符可能不使用索引索引查找并非总是首选! NOT 运算符 当查询包含NOT运算符时,很可能不使用索引,就像使用OR运算符一样。...隔离条件的列 另外,如果列被用在计算或标量函数,也不会使用索引。一个可能的解决方案是仅隔离指定列,使其不再是计算或函数的一部分。...通过将一个哈希函数应用于连接属性来访问哈希。 一旦构建了哈希,就会扫描较大的,并通过查看哈希来查找较小的相关行。

1.7K40

《一切皆是映射》哈希算法 (Hash)

: 左移运算符,num << 1,相当于num乘以2 低位补0 >> : 右移运算符,num >> 1,相当于num除以2 高位补0 >>> : 无符号右移,忽略符号位,空位都以0补齐 % : 运算...哈希就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值key,即可查找到其对应的值。...使用哈希查找有两个步骤: 1.使用哈希函数将被查找的键转换为数组的索引。在理想的情况下,不同的键会被转换为不同的索引值,但是在有些情况下我们需要处理多个键被哈希到同一个索引值的情况。...所以哈希查找的第二个步骤就是处理冲突 2.处理哈希碰撞冲突。有很多处理哈希碰撞冲突的方法,本文后面会介绍拉链法和线性探测法。 哈希是一个时间和空间上做出权衡的经典例子。...哈希使用了适度的时间和空间来在这两个极端之间找到了平衡。只需要调整哈希函数算法即可在时间和空间上做出取舍。

1.3K20

为什么 HashMap 的容量大小要设置为2的N次方?

HashMap 是基于哈希的 Map 接口的实现,线程不安全,且不保证映射顺序。 HashMap 存储数据依赖的是数组和[链表|红黑树],具体链表和红黑树之间如何转换的细节此文不做详细介绍。...0 : (h = key.hashCode()) ^ (h >>> 16); } 为什么直接使用 key.hashCode()的值,我们后面会提到。...计算出来哈希值后,由于数组容量相对来说较小肯定不能直接使用哈希值当作索引值。所以需要使用哈希值对数组长度减一后的值取。不过在在 HashMap 可不是直接使用 % 运算符来操作的。...,那么证明为什么实例化 HashMap 对象的容量要使用2的N次方就简单多了。...哦,前面说为什么计算出来的散列值需要再让高16位和低十六位做异或运算,主要是让参与与运算的位同时具有高位和低位的特征,来减少哈希碰撞次数。

1.4K00

分布式缓存--一致性hash原理和hash槽,以及算法实现

一致性哈希算法1997年由麻省理工学院提出,设计目标是为了解决因特网的热点(Hot spot)问题,初衷和CARP十分类似。...一致性哈希修正了CARP使用的简单哈希算法带来的问题,使得DHT可以P2P环境真正得到应用。...hash槽 redis cluster里面使用的方法,一个 Redis Cluster包含16384(0~16383)个哈希槽,存储Redis Cluster的所有键都会被映射到这些slot...集群的每个键都属于这16384个哈希的一个,集群使用公式slot=CRC16(key)/16384来计算key属于哪个槽,其中CRC16(key)语句用于计算key的CRC16校验和。...虚拟节点 服务节点较少的时候,容易出现hash环倾斜的情况,大量数据分布少部分节点上,如图: ?

95830

EFFICIENCY IN THE COLUMBIA DATABASE QUERY OPTIMIZER(翻译)优化器架构

索引擎 图12 说明了Columbia搜索引擎的三个重要组成部分及其关系。搜索空间通过复制初始查询表达式来进行初始化。优化器的目标是扩展搜索空间,并从最终搜索空间中找到最优(最小成本)的计划。...搜索空间包含一个静态哈希。多表达式的三个组成部分,算子类名、算子参数和输入组编号,都被哈希哈希以检查重复。...lookup2的另一个优点是其哈希的大小是2的幂次,这允许对这样的哈希大小进行非常快速的运算。相反,传统的哈希函数需要对一个质数进行运算,这比对2的幂次进行运算要慢得多。...以下是FindDup的算法:计算多表达式的哈希值,然后查找哈希以查看是否存在冲突。...我们需要对每个物理多表达式使用新的上下文执行 O_INPUTS,以计算物理多表达式的成本,并在可能的情况下为该上下文生成一个优胜者。 Cascades ,优化组的任务涉及物理子树。

29530

微软员工聊C#的IDisposable接口

它不过是把内部数组 HashValue 的每个元素清零,然后把指针设为 null。...这个库代码作者没有搞明白的是,如果你的 Dispose 方法只是把一些成员设为 null,那么你根本就不需要实现 IDisposable。为什么呢?...有些人问,要是 Foo 对象被放进一个全局哈希之类的数据结构,GC 没法释放它,就需要 Dispose 了吧?这也是一种常见的误解。...一旦哈希对 Foo 对象的引用没有了,GC 运行的时候就会发现它成了垃圾,里面的 _data 数组自然也是垃圾,所以一起就回收掉了。 所以简言之,Dispose 不是用来给你回收内存用的。...无论你是否调用它们的 Dispose 方法,系统性能都一一样。只不过如果你调用 Dispose,计算花的时间还要稍微多一些。

19940

技术译文 | 数据库索引算法的威力:B-Tree 与 Hash 索引

哈希索引的工作原理是根据哈希值将的每条记录映射到唯一的存储桶。哈希值是使用哈希函数计算的,哈希函数是一种以数据项作为输入并返回唯一整数值的数学函数。...为了哈希索引查找记录,数据库计算搜索键的哈希值,然后查找相应的存储桶。如果该记录在存储桶,则数据库将返回该记录。否则,数据库执行全扫描。...哈希索引的查找速度非常快,但它们不能用于有效地查询数据范围。这是因为哈希函数不保留记录之间的任何顺序。 要使用哈希索引执行查询: 数据库计算查询条件的哈希值。 哈希查找对应的哈希桶。...某些情况下,哈希索引可能不是最佳选择: 哈希索引查找方面比树索引更快(对于使用 = 或 运算符的相等比较),但它们不能用于有效地查询数据范围。...Hash Hash 索引的工作原理是根据哈希值将的每条记录映射到唯一的存储桶。哈希值是使用哈希函数计算的。哈希索引将数据随机分布存储桶,导致范围查询效率低下。

18710

Redis 字典

dictht哈希, 一般情况下,字典只使用ht0 哈希,ht1哈希只会对ht0哈希进行rehash时使用。...dictEntry **table; //哈希大小 unsigned long size; //哈希大小掩码,用于计算索引值 unsigned long sizemask...说明: 1、因为进行渐进式 rehash 的过程,字典会同时使用 ht0 和 ht1 两个哈希,所以渐进式 rehash 进行期间,字典的删除(delete)、查找(find)、更新(update...2、渐进式 rehash 执行期间,新添加到字典的键值对一律会被保存到 ht1 里面,而 ht0 则不再进行任何添加操作:这一措施保证了 ht0 包含的键值对数量会只减增,并随着 rehash 操作的执行而最终变成空...每个字典有两个哈希,一个是正常使用,一个用于rehash期间使用。 当redis计算哈希时,采用的是MurmurHash2哈希算法。

1.7K84

【动态图】教你捋清Java常用数据结构及其设计原理

get(index) 也是会先判断index, 不过性能依然不好, 这也是为什么推荐用for(int i = 0; i < lengh; i++)的方式遍历linkedlist, 而是使用iterator...遇到运算符(加减乘除):弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 最终将栈的元素依次出栈,输出。 ?...HashMap 最常用的哈希, 面试的童鞋必备知识了, 内部通过数组 + 单链表的方式实现. jdk8引入了红黑树对长度 > 8的链表进行优化, 我们另外篇幅再讲. put(K, V) ?...具体操作如下: jdk7对所有元素直接rehash, 并放到新的位置....jdk8判断元素原hash值新增的bit位是0还是1, 0则索引不变, 1则索引变成"原索引 + oldTable.length". 1 //定义两条链 2 //原来的hash值新增的

45220

图解Java常用数据结构(一)

get(index) 也是会先判断index, 不过性能依然不好, 这也是为什么推荐用for(int i = 0; i < lengh; i++)的方式遍历linkedlist, 而是使用iterator...遇到运算符(加减乘除):弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 最终将栈的元素依次出栈,输出。 ?...HashMap 最常用的哈希, 面试的童鞋必备知识了, 内部通过数组 + 单链表的方式实现. jdk8引入了红黑树对长度 > 8的链表进行优化, 我们另外篇幅再讲. put(K, V) ?...具体操作如下: jdk7对所有元素直接rehash, 并放到新的位置....jdk8判断元素原hash值新增的bit位是0还是1, 0则索引不变, 1则索引变成"原索引 + oldTable.length". 1 //定义两条链 2 //原来的hash值新增的

1.4K30

图解Java常用数据结构(一)

get(index) 也是会先判断index, 不过性能依然不好, 这也是为什么推荐用for(int i = 0; i < lengh; i++)的方式遍历linkedlist, 而是使用iterator...遇到运算符(加减乘除):弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 最终将栈的元素依次出栈,输出。 ?...HashMap 最常用的哈希, 面试的童鞋必备知识了, 内部通过数组 + 单链表的方式实现. jdk8引入了红黑树对长度 > 8的链表进行优化, 我们另外篇幅再讲. put(K, V) ?...具体操作如下: jdk7对所有元素直接rehash, 并放到新的位置....jdk8判断元素原hash值新增的bit位是0还是1, 0则索引不变, 1则索引变成"原索引 + oldTable.length". 1 //定义两条链 2 //原来的hash值新增的

46650

《求求大厂给个Offer》Map面试题

三歪:“首先要明确的是:Java里边,哈希的结构是数组+链表的方式。...HashMap里用的是位运算来代替取,能够更加高效地算出该元素所在的位置。为什么HashMap的大小只能是2次幂,因为只有大小为2次幂时,才能合理用位运算替代取。”...显然是可以的,但是推荐。负载因子调高了,这意味着哈希冲突的概率会增高,哈希冲突概率增高,同样会耗时(因为查找的速度变慢了)” ?...三歪:”put的时候,首先对key做hash运算,计算出该key所在的index。如果没碰撞,直接放到数组,如果碰撞了,需要判断目前数据结构是链表还是红黑树,根据不同的情况来进行插入。...最后判断哈希是否满了(当前哈希大小*负载因子),如果满了,则扩容“ 三歪:”get的时候,还是对key做hash运算,计算出该key所在的index,然后判断是否有hash冲突,假设没有直接返回,

35540

Java Map 集合类简介

以下是一个简单的、适用于任何对象的 Java 哈希函数 int hashvalue = Maths.abs(key.hashCode()) % table.length; (% 二进制运算符...哈希映射的术语,这称作冲突。Map 处理这些冲突的方法是索引位置处插入一个链接列表,并简单地将元素添加到此链接列表。...( get() 方法与 put() 方法具有相同的算法,但 get() 包含插入和覆盖代码。)...调整 Map 实现的大小 哈希术语,内部数组的每个位置称作“存储桶”(bucket),而可用的存储桶数(内部数组的大小)称作容量 (capacity)。...调整大小需要将所有元素重新插入到新数组,这是因为不同的数组大小意味着对象现在映射到不同的索引值。先前冲突的键可能不再冲突,而先前冲突的其他键现在可能冲突。

1.6K30

动图+源码+总结:演示 JDK8 的数据结构(珍藏版)

get(index) 也是会先判断index, 不过性能依然不好, 这也是为什么推荐用for(int i = 0; i < lengh; i++)的方式遍历linkedlist, 而是使用iterator...5、遇到运算符(加减乘除):弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 6、最终将栈的元素依次出栈,输出。 ?...计算后缀表达 1、遇到数字时,将数字压入堆栈 2、遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算, 并将结果入栈 3、重复上述过程直到表达式最右端 4、运算得出的值即为表达式的结果 ?...HashMap 最常用的哈希, 面试的童鞋必备知识了, 内部通过数组 + 单链表的方式实现. jdk8引入了红黑树对长度 > 8的链表进行优化, 我们另外篇幅再讲. put(K, V*)* ?...具体操作如下: 1、jdk7对所有元素直接rehash, 并放到新的位置. 2、jdk8判断元素原hash值新增的bit位是0还是1, 0则索引不变, 1则索引变成"原索引 + oldTable.length

38020

Java | 图解数据结构及原理,傻瓜也能看懂!

get(index) 也是会先判断index, 不过性能依然不好, 这也是为什么推荐用for(int i = 0; i < lengh; i++)的方式遍历linkedlist, 而是使用iterator...遇到运算符(加减乘除):弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 最终将栈的元素依次出栈,输出。 ?...HashMap 最常用的哈希, 面试的童鞋必备知识了, 内部通过数组 + 单链表的方式实现. jdk8引入了红黑树对长度 > 8的链表进行优化, 我们另外篇幅再讲。 ? put(K, V) ?...具体操作如下: jdk7对所有元素直接rehash, 并放到新的位置....jdk8判断元素原hash值新增的bit位是0还是1, 0则索引不变, 1则索引变成"原索引 + oldTable.length". 1 //定义两条链 2 //原来的hash值新增的bit为0的链

65740

图解 Java 的数据结构及原理,傻瓜也能看懂!

get(index) 也是会先判断index, 不过性能依然不好, 这也是为什么推荐用for(int i = 0; i < lengh; i++)的方式遍历linkedlist, 而是使用iterator...遇到运算符(加减乘除):弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 最终将栈的元素依次出栈,输出。 ?...HashMap 最常用的哈希, 面试的童鞋必备知识了, 内部通过数组 + 单链表的方式实现. jdk8引入了红黑树对长度 > 8的链表进行优化, 我们另外篇幅再讲。...具体操作如下: jdk7对所有元素直接rehash, 并放到新的位置....jdk8判断元素原hash值新增的bit位是0还是1, 0则索引不变, 1则索引变成"原索引 + oldTable.length". 1 //定义两条链 2 //原来的hash值新增的

44920
领券