为什么HashMap建议初始化容量,且容量为2的次幂?

HashMap有扩容机制,就是当达到扩容条件时会进行扩容。HashMap的扩容条件就是当HashMap中的元素个数(size)超过临界值(threshold)时就会自动扩容。在HashMap中,threshold = loadFactor * capacity

每次扩容会重建hash表,导致性能下降。

默认情况下,当我们设置HashMap的初始化容量时,实际上HashMap会采用第一个大于该数值的2的幂作为初始化容量。

计算hashMap容量的阈值:

static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

<<左移*2,右边补0

>>右边移/2,左边补符号位,符号位是0就补0,是1就补1

>>>无符号右移,全补0

原文地址:https://www.cnblogs.com/akaneblog/p/12616982.html

时间: 2024-08-03 18:45:13

为什么HashMap建议初始化容量,且容量为2的次幂?的相关文章

jdk1.8 HashMap底层数据结构:深入解析为什么jdk1.8 HashMap的容量一定要是2的n次幂

前言 1.本文根据jdk1.8源码来分析HashMap的容量取值问题: 2.本文有做 jdk1.8 HashMap.resize()扩容方法的源码解析:见下文“一.3.扩容:同样需要保证扩容后的容量是2的n次幂”: 3.目录: 一.jdk1.8中,对“HashMap的容量一定是2的n次幂”做了严格控制 1.默认初始容量 2.使用HashMap的有参构造函数来自定义容量的大小(保证容量是2的n次幂) 3.扩容:同样需要保证扩容后的容量是2的n次幂( jdk1.8 HashMap.resize()扩

HashMap 与 ConcurrentHashMap 在初始化不同大小容量时,实际分配的空间情况

HashMap.java  int capacity = 1;      int initialCapacitys[] = {1,2,3,4,5,6,7,8,9,10,11,13,15,16,17,26,31,32,33,50,60,63,64,65};      for(int initialCapacity : initialCapacitys) {     while (capacity < initialCapacity)         capacity <<= 1;     

Java中的ArrayList的初始容量和容量分配

List接口的大小可变数组的实现.实现了所有可选列表操作,并允许包括 null 在内的所有元素.ArrayList继承于List接口,除继承过来的方法外,还提供一些方法来操作内部用来存储列表的数组的大小.每个ArrayList实例都有一个容量.该容量是指用来存储列表元素的数组的大小.它总是至少等于列表的大小.随着向ArrayList中不断添加元素,其容量也自动增长.并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单. ArrayList是经常会被用到的,一般情况下,使用的

ArrayList,HashMap,LinkedList 初始化大小和 扩容机制

参见:https://blog.csdn.net/zuochao_2013/article/details/80974963?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task 原文地址:https://www.cnblogs.com/chaojibaidu/p/12619499.html

JDK源码分析系列-ArrayList

1.ArrayList本质 数组 + 动态扩容实现的数据列表. private static final Object[] EMPTY_ELEMENTDATA = {}; // elementData初始为空数组 public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; } // 指定初始容量,不能为负数 // 如果能预估集合大小,建议初始化时指定容量,避免扩容,提升性能 public ArrayList(int in

HashMap初始化容量过程

集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生.在日常开发中,我们经常会像如下方式以下创建一个HashMap: Map<String, String> map = new HashMap<String, String>(); 但是,大家有没有想过,上面的代码中,我们并没有给HashMap指定容量,那么,这时候一个新创建的HashMap的默认容量是多少呢?为什么呢?本文就来分析下这个问题. 什么是容量 在J

常用容器制定初始化容量

前面在javaSe中我已经整理了相关的一些数据结构,现在就性能方面在这里做一个总结.以后在实际编码中,应该按照这样子来初始化相关的数据结构. 1,StringBuffer和StringBuilder StringBuffer()           构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符. StringBuffer(int capacity)           构造一个不带字符,但具有指定初始容量的字符串缓冲区. 关于这2个类本身的区别和性能我就不做重复了,一般的情况下我

HashMap 源码解析(一)之使用、构造以及计算容量

简介 HashMap 是基于哈希表的 Map 接口的实现. 它的使用频率是非常的高. 集合和映射 作为集合框架中的一员,在深入之前, 让我们先来简单了解一下集合框架以及 HashMap 在集合框架中的位置. 从图中可以看出 集合框架分为两种, 即集合(Collections)和映射(Map) HashMap 是 AbstractMap 的子类.而 AbstractMap 实现了 Map, 因此它有 Map 的特性. 通过Map接口, 可以生成集合(Collections). 那集合(Collec

Java提高篇(三五)-----Java集合细节(一):请为集合指定初始容量

集合是我们在Java编程中使用非常广泛的,它就像大海,海纳百川,像万能容器,盛装万物,而且这个大海,万能容器还可以无限变大(如果条件允许).当这个海.容器的量变得非常大的时候,它的初始容量就会显得很重要了,因为挖海.扩容是需要消耗大量的人力物力财力的.同样的道理,Collection的初始容量也显得异常重要.所以:对于已知的情景,请为集合指定初始容量. public static void main(String[] args) { StudentVO student = null; long