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

调用 indexFor(int h, int length) 方法来计算 table 数组的哪个索引处

但是,“模”运算的消耗还是比较大的,在HashMap中是这样做的:调用 indexFor(int h, int length) 方法来计算该对象应该保存在 table 数组的哪个索引处。...的hashCode的进一步优化,加入了高位计算,就使得只有相同的hash值的两个值才会被放到数组中的同一个位置上形成链表。   ...所以说,当数组长度为2的n次幂的时候,不同的key算得的index相同的几率较小,那么数据在数组上分布就比较均匀,也就是说碰撞的几率小,相对的,查询的时候就不用遍历某个位置上的链表,这样查询效率也就较高了...并且扩容的时候不必全部重新计算hash,只需要判断最高位。...从上面的源代码中可以看出:从HashMap中get元素时,首先计算key的hashCode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。

34400
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    大厂面试HashMap,很多人栽在了这儿

    HashMap的数据结构 ---- 先了解一下HashMap的数据结构,在java中,数组和链表是最常用的两个基础数据结构,很多集合类都基于他们实现。...可能很多人想到了用hashcode对数组长度取模得到数组下标位置,不错,取模的方式确实可以让数据分布比较均匀。但是,有没有更好的方式呢? ?...HashMap的长度是16(2的4次幂)时,它的二进制是10000,(n-1)的二进制是01111,与hash值的计算结果如上图所示。...再看看HashMap的长度不是2的N次幂的情况,假设长度是10,它的二进制是01010,(n-1)的二进制是01001,与hash值的计算结果如上图所示。...所以,当数组长度为2的n次幂时,不同的key通过位运算获取的数组下标冲突的几率会比较小。冲突少了,添加元素的效率自然会更高,数据在数组上的分布也会更均匀,相应的链表长度也比较短。

    52330

    Java集合必会14问(精选面试题整理)

    O(n),为了针对这个问题,JDK1.8在HashMap中新增了红黑树的数据结构,进一步使得遍历复杂度降低至O(logn); 总结 简单总结一下HashMap是使用了哪些方法来有效解决哈希冲突的: 1....答: HashMap自己实现了自己的hash()方法,通过两次扰动使得它自己的哈希值高低位自行进行异或运算,降低哈希碰撞概率也使得数据分布更平均; 在保证数组长度为2的幂次方的时候,使用hash()运算之后的值与运算...(&)(数组长度 - 1)来获取数组下标的方式进行存储,这样一来是比取余操作更加有效率,二来也是因为只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,三来解决了“哈希值与数组大小范围不匹配...”的问题; 面试官:为什么数组长度要保证为2的幂次方呢?...答: 只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,即实现了key的定位,2的幂次方也可以减少冲突次数,提高HashMap的查询效率; 如果 length 为 2 的次幂

    59430

    Java集合必会14问(精选面试题整理)

    O(n),为了针对这个问题,JDK1.8在HashMap中新增了红黑树的数据结构,进一步使得遍历复杂度降低至O(logn); 总结 简单总结一下HashMap是使用了哪些方法来有效解决哈希冲突的: 1....答: HashMap自己实现了自己的hash()方法,通过两次扰动使得它自己的哈希值高低位自行进行异或运算,降低哈希碰撞概率也使得数据分布更平均; 在保证数组长度为2的幂次方的时候,使用hash()运算之后的值与运算...(&)(数组长度 - 1)来获取数组下标的方式进行存储,这样一来是比取余操作更加有效率,二来也是因为只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,三来解决了“哈希值与数组大小范围不匹配...”的问题; 面试官:为什么数组长度要保证为2的幂次方呢?...答: 只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,即实现了key的定位,2的幂次方也可以减少冲突次数,提高HashMap的查询效率; 如果 length 为 2 的次幂

    49660

    Java集合必会14问(精选面试题整理)

    O(n),为了针对这个问题,JDK1.8在HashMap中新增了红黑树的数据结构,进一步使得遍历复杂度降低至O(logn); 总结 简单总结一下HashMap是使用了哪些方法来有效解决哈希冲突的: 1....答: HashMap自己实现了自己的hash()方法,通过两次扰动使得它自己的哈希值高低位自行进行异或运算,降低哈希碰撞概率也使得数据分布更平均; 在保证数组长度为2的幂次方的时候,使用hash()运算之后的值与运算...(&)(数组长度 - 1)来获取数组下标的方式进行存储,这样一来是比取余操作更加有效率,二来也是因为只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,三来解决了“哈希值与数组大小范围不匹配...”的问题; 面试官:为什么数组长度要保证为2的幂次方呢?...答: 只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,即实现了key的定位,2的幂次方也可以减少冲突次数,提高HashMap的查询效率; 如果 length 为 2 的次幂

    44320

    面霸篇:Java 核心集合容器全解(核心卷二)

    HashMap 的长度为什么是 2 的幂次方 HashMap 和 ConcurrentHashMap 的区别 ConcurrentHashMap 实现原理 点击下方卡片,关注「码哥字节」 集合容器概述...集合的特点 对象封装数据,多个对象需要用集合存储; 对象的个数可以确定使用数组更高效,不确定个数的情况下可以使用集合,因为集合是可变长度。 集合与数组的区别 数组是固定长度的;集合可变长度的。...我们可以从一个 Collection 中使用迭代器方法来获取迭代器实例。 迭代器取代了 Java 集合框架中的 Enumeration,迭代器允许调用者在迭代过程中移除元素。...线程安全:ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全; 综合来说,在需要频繁读取集合中的元素时,更推荐使用 ArrayList,而在插入和删除操作较多时,更推荐使用...String、Integer 等包装类的特性能够保证 Hash 值的不可更改性和计算准确性,能够有效的减少 Hash 碰撞的几率。

    37421

    Java集合容器面试题(2020最新版)

    按照函数注释,因为bucket数组大小是2的幂,计算下标index = (table.length - 1) & hash,如果不做 hash 处理,相当于散列生效的只有几个低 bit 位,为了减少散列的碰撞...O(n),为了针对这个问题,JDK1.8在HashMap中新增了红黑树的数据结构,进一步使得遍历复杂度降低至O(logn); 总结 简单总结一下HashMap是使用了哪些方法来有效解决哈希冲突的: 1....答:String、Integer等包装类的特性能够保证Hash值的不可更改性和计算准确性,能够有效的减少Hash碰撞的几率 都是final类型,即不可变性,保证key的不可更改性,不会存在获取hash值不同的情况...HashMap自己实现了自己的hash()方法,通过两次扰动使得它自己的哈希值高低位自行进行异或运算,降低哈希碰撞概率也使得数据分布更平均; 在保证数组长度为2的幂次方的时候,使用hash()运算之后的值与运算...(&)(数组长度 - 1)来获取数组下标的方式进行存储,这样一来是比取余操作更加有效率,二来也是因为只有当数组长度为2的幂次方时,h&(length-1)才等价于h%length,三来解决了“哈希值与数组大小范围不匹配

    1.2K20

    一、简单使用二、 并行循环的中断和跳出三、并行循环中为数组集合添加项四、返回集合运算结果含有局部变量的并行循环五、PLinq(Linq的并行计算)

    这里我们可以看出并行循环在执行效率上的优势了。 结论1:在对一个数组内的每一个项做单独处理时,完全可以选择并行循环的方式来提升执行效率。...原理1:并行计算的线程开启是缓步开启的,线程数量1,2,4,8缓步提升。...三、并行循环中为数组/集合添加项 上面的应用场景其实并不是非常多见,毕竟只是为了遍历一个数组内的资源,我们更多的时候是为了遍历资源,找到我们所需要的。那么请继续看。...ConcurrentBag 表示对象的线程安全的无序集合。 ConcurrentDictionary 表示可由多个线程同时访问的键值对的线程安全集合。...五、PLinq(Linq的并行计算) 上面介绍完了For和ForEach的并行计算盛宴,微软也没忘记在Linq中加入并行计算。下面介绍Linq中的并行计算。

    2.6K61

    【Java编程进阶之路 03】深入探索:HashMap的长度为什么是2的幂次方

    当数组的长度是2的幂次方时,哈希函数可以利用位运算来快速计算索引位置,这有助于实现更均匀的分布。...此外,使用2的幂次方作为长度还可以简化内存分配和释放的过程,因为计算机系统通常使用2的幂次方大小的块来分配和释放内存。...05 历史与兼容性 最后,HashMap的长度选择为2的幂次方也受到了历史和兼容性的影响。在Java的早期版本中,HashMap就已经采用了这种设计方式,并且被证明是有效的。...随着Java的发展和演变,这种设计方式被保留了下来,并且成为了Java集合框架中哈希表实现的一种标准做法。保持这种设计方式也有助于确保Java与其他编程语言和库的兼容性。...由于新容量也是2的幂次方,元素在扩容后的新数组中的索引可以通过简单的位运算得到,而不需要重新计算哈希值。这种特性大大简化了扩容过程中元素的迁移操作,提高了HashMap的性能。

    31110

    java-集合

    Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。Map保存键值对(key-value pair)映射,映射关系可以是一对一或多对一。...List 适用于按数值索引访问元素的情形。 Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值。...相对于ArrayList,LinkedList的插入,添加,删除操作速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。...1.7size计算是先采用不加锁的方式,连续计算元素的个数,最多计算3次:1、如果前后两次计算结果相同,则说明计算出来的元素个数是准确的;2、如果前后两次计算结果都不同,则给每个Segment进行加锁,...HashMap的容量为什么是2的n次幂 HashMap是根据key的hash值决策key放入到哪个桶(bucket)中,通过 tab=[(n - 1) & hash] 公式计算得出,n为table的长度

    60810

    Java 并发(9)ConcurrentHashMap 源码分析

    现在我们看到核心构造器的代码,首先是通过传入的 concurrencyLevel 来计算出 ssize,ssize 是 Segment 数组的长度,它必须保证是 2 的幂,这样就可以通过 hash&ssize...由于传入的 concurrencyLevel 不能保证是 2 的幂,所以不能直接用它来当作 Segment 数组的长度,因此我们要找到一个最接近 concurrencyLevel 的 2 的幂,用它来作为数组的长度...的 2 的幂,将这个值赋给 cap,然后用 cap 来作为 HashEntry 数组的长度。...get 方法是通过下标来访问数组元素的,而在 JDK1.7 中是通过 UnSafe 的 getObjectVolatile 方法来读取数组中的元素。...在上面代码中我们可以看到首先是根据 key 的哈希码来计算出分段锁在数组中的下标,然后根据下标使用 UnSafe 类 getObject 方法来读取分段锁。

    62210

    Java 并发编程之 ConcurrentHashMap 源码分析(小长文)

    现在我们看到核心构造器的代码,首先是通过传入的concurrencyLevel来计算出ssize,ssize是Segment数组的长度,它必须保证是2的幂,这样就可以通过hash&ssize-1来计算分段锁在数组中的下标...由于传入的concurrencyLevel不能保证是2的幂,所以不能直接用它来当作Segment数组的长度,因此我们要找到一个最接近concurrencyLevel的2的幂,用它来作为数组的长度。...分段锁的容量也就是HashEntry数组的长度,同样也必须保证是2的幂,而上面算出的c的值不能保证这一点,所以不能直接用c作为HashEntry数组的长度,需要另外找到一个最接近c的2的幂,将这个值赋给...方法是通过下标来访问数组元素的,而在JDK1.7中是通过UnSafe的getObjectVolatile方法来读取数组中的元素。...在上面代码中我们可以看到首先是根据key的哈希码来计算出分段锁在数组中的下标,然后根据下标使用UnSafe类getObject方法来读取分段锁。

    68830

    一道算术题:ArrayDeque + ArrayList = LinkedList

    如果初始容量大于 8,则计算 “最近的 2 的整数幂” 作为初始大小。例如 numElements 为 8,则初始化容量为 16。...numElements 为 19,则初始化容量为 32; 3、带集合的构造方法: 用相同的方法创建初始容量为 2 的整数幂的数组,并调用 addAll 逐个添加元素。...在循环数组中需要使用取余运算计算游标指针循环后的位置,例如 (tail + 1) % size,而如果数组的尺寸 size 是 2 的整数幂,那么就可以将取余运算替换为位运算,例如 (tail + 1)...再执行 +1 运算,就求出了最近的 2 的整数幂(最高有效位是 1,低位都是 0); 3、当 numElements 在 2^30 到 2^ 31-1 之间(即最高位是 0100 的数),计算后得到的...int size = s.readInt(); // 计算最近的 2 的整数幂 int capacity = calculateSize(size); // 分配数组

    50320

    Java基础知识:HashMap(一)

    JDK 1.8 之前 HashMap 由 数组+链表 组成,数组是 HashMap 的主体,链表则是主要为了解决 哈希冲突(两个对象调用的 hashCode 方法计算的哈希值一致导致计算的数组索引值相同...2 HashMap底层数据结构 2.1 数据结构概念 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在的一种或多种特定关系的数据元素的集合。...如果计算出的索引空间没有数据,则直接将该键值对存储到数组中; 例如:(对照图)计算出的索引是 3,则 “小明-5” 就被放入第 3 个位置; 向哈希表中存储数据 王阿姨-23 ,假设该键值对结合数组长度计算出的索引值也是...如果创建 HashMap 对象时,输入的数组长度不是 2 的幂次方,HashMap 会通过不断的位运算和或运算得到距离其最近的 2 的幂次方的数。...如果 cap 已经是 2 的幂次方,有没有执行 - 1 的操作,则执行完后面的无符号右移草组织好,返回的 capacity 将是这个 cap 的 2 倍。

    86511

    如何保证集合是线程安全的? ConcurrentHashMap如何实现高效地线程安全?

    梳理并发包内,尤其是ConcurrentHashMap采取了哪些方法来提高并发表现。最好能够掌握ConcurrentHashMap自身的演进,目前的很多分析资料还是基于其早期版本。...注意,Java需要它是2的幂数值,如果输入是类似15这种非幂值,会被自动调整到16之类2的幂数值。具体情况,我们一起看看一些Map基本操作的源码,这是JDK 7比较新的get代码。...试想,如果不进行同步,简单的计算所有Segment的总值,可能会因为并发put,导致结果不准确,但是直接锁定所有Segment进行计算,就会变得非常昂贵。其实,分离锁也限制了Map的初始化等操作。...总体结构上,它的内部存储变得和我在专栏上一讲介绍的HashMap结构非常相似,同样是大的桶(bucket)数组,然后内部也是一个个所谓的链表结构(bin),同步的粒度要更细致一些。...你有没有注意到,在同步逻辑上,它使用的是synchronized,而不是通常建议的ReentrantLock之类,这是为什么呢?

    45120

    Java基础之集合

    length(默认16,即1的次幂保证length-1的所有二进制位的值全为1,这种情况下计算出的数组索引等同于hashCode后几位的值,这样hash算法的结果就会比较均匀的分布)乘以负载因子...没超过最大值那就扩容为原来的2倍(左移1位)。接着计算新的阈值。然后是一个for循环,将元素拷贝到新数组里。...另外hashtable的迭代器是安全失败的,hashmap是快速失败的,后者在遍历集合时会检测元素有没有发生变化,通过modcount变量,监测它的值,如果不符合预期说明元素被增加、删除或修改了就抛出异常...为什么默认是10 据说是因为sun的程序员对一系列广泛使用的程序代码进行了调研,结果就是10这个长度的数组是最常用的最有效率的。...CopyOnWriteArraySet:CopyOnWriteArraySet逻辑就更简单了,就是使用 CopyOnWriteArrayList 的 addIfAbsent 方法来去重的,添加元素的时候判断对象是否已经存在

    28510

    2019年Java面试题基础系列228道(6),查漏补缺!

    52、用哪两种方式来实现集合的排序? 53、Java 中怎么打印数组? 54、Java 中的 LinkedList 是单向链表还是双向链表? 55、Java 中的 TreeMap 是采用什么树实现的?...你可以使用有序集合,如 TreeSet 或 TreeMap,你也可以使用有顺序的的集合,如 list,然后通过 Collections.sort() 来排序。 53、Java 中怎么打印数组?...你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法来打印数组。...60、ArrayList 和 HashMap 的默认大小是多数? 在 Java 7 中,ArrayList 的默认大小是 10 个元素,HashMap 的默认大小是16 个元素(必须是 2 的幂)。...c)如果可以,更偏向于使用 volatile 而不是 synchronized。

    96600

    Java集合面试题&知识点总结(下篇)

    为什么 HashMap 的扩容长度是 2 的幂次方? 解答:HashMap 的扩容长度选择 2 的幂次方,主要是为了优化哈希值的计算过程。...如果 HashMap 的容量为 2 的幂次方,那么哈希值的计算可以简化为:index = hashCode & (length-1),这种位运算的效率要高于除法运算。...在 HashTable 中,键和值都是通过 equals() 和 hashCode() 方法来进行比较和哈希值计算的。...以上就是 SortedMap 的基本概念。它是用于创建可以自动排序的映射,提供了丰富的方法来操作排序后的键值对。 2.7、JavaMap集合相关-NavigableMap 问题 60....以上就是 NavigableSet 的基本概念。它是用于创建可以进行导航的集合,提供了丰富的方法来操作排序后的元素。

    21820

    JAVA 持有对象——容器初探

    但是,Java类库中使用了Collection来指代集合类中的子集{List,Queue,Set},所以集合类也被称为容器。容器提供了完善的方法来保存对象。...当使用无参构造函数时数组长度默认为空,当向ArrayList加入对象时,会调用一个方法来判断数组是否能放下这个对象。...若大于等于最小长度,则找到比给定长度大的最小的2的幂数。为什么要是2的幂数呢?...原因有以下两点: 操作系统分配内存的方法使用伙伴系统的话,每一块的大小都是2的幂数,如果分配的内存大小为2的幂数,可以减少内存分配的时间。...使用2的幂数能够有效判断头部所在的地址。 同样在第二点中,如果队列满了,数组扩充是将容量capacity值左移一位即可扩充一倍。

    42720

    扫码

    添加站长 进交流群

    领取专属 10元无门槛券

    手把手带您无忧上云

    扫码加入开发者社群

    相关资讯

    热门标签

    活动推荐

      运营活动

      活动名称
      广告关闭
      领券