惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
博客园_首页
M
MIT News - Artificial intelligence
Project Zero
Project Zero
C
CXSECURITY Database RSS Feed - CXSecurity.com
V2EX - 技术
V2EX - 技术
G
Google Developers Blog
H
Hacker News: Front Page
N
Netflix TechBlog - Medium
Martin Fowler
Martin Fowler
GbyAI
GbyAI
C
Cisco Blogs
www.infosecurity-magazine.com
www.infosecurity-magazine.com
酷 壳 – CoolShell
酷 壳 – CoolShell
The Hacker News
The Hacker News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Simon Willison's Weblog
Simon Willison's Weblog
A
Arctic Wolf
H
Heimdal Security Blog
量子位
小众软件
小众软件
Help Net Security
Help Net Security
博客园 - Franky
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News | PayPal Newsroom
T
Tor Project blog
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
N
News and Events Feed by Topic
T
Tailwind CSS Blog
Webroot Blog
Webroot Blog
J
Java Code Geeks
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
罗磊的独立博客
The Register - Security
The Register - Security
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
有赞技术团队
有赞技术团队
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
腾讯CDC
P
Palo Alto Networks Blog
S
Secure Thoughts
D
Darknet – Hacking Tools, Hacker News & Cyber Security
TaoSecurity Blog
TaoSecurity Blog
Scott Helme
Scott Helme
T
Tenable Blog
C
Cybersecurity and Infrastructure Security Agency CISA
D
Docker
美团技术团队

博客园 - 有容乃大

GitHub相关 2022又要重新找工作开始新的历程 java之面向对象详解(转) java关于for循环的效率优化 JAVA线程池ThreadPoolExecutor的分析和使用(新手踩坑和推荐方案) JAVA常量池 Java String的intern()注意事项(分JDK1.6及JDK1.7) JAVA的类加载过程 使用RabbitMQ实现延迟任务 JAVA三元运算符空指针引用的坑 Java中static块、构造块、构造函数的执行顺序 Ansj中文分词 将异常对象转为字符串 JVM的内存区域划分 深入理解Java String类(综合) 理解JAVA的IO 理解Java注解类型 JAVA中Integer的==和equals注意 JVM原理摘要
关于HashMap、HashSet和ArrayList集合对象容量初始值设置及扩容演示
有容乃大 · 2020-01-15 · via 博客园 - 有容乃大

ArrayList:
-------------------------------------
明确知道容量:直接设置初始容量,如new ArrayList<>(100)
无法确定容量:预估一个比较接近的值,如果实在无法确定,则无需指定初始值 (有默认值)
ArrayList没有加载因子,初始容量10,扩容增量为原来的0.5倍取整


HashMap(HashSet规则相同)
-------------------------------------
HashMap的默认加载因子为0.75,但可以使用构造器指定,如new HashMap<>(100, 1),此时指定加载因子为1
故计算HashMap的初始值时的工式为:(int) (realSize / loadFactor) + 1

如果实际容量为100,加载因子为默认(0.75),计算容量为:(int) (100 / 0.75) + 1 = 134,则实例化HashMap为 new HashMap<>(134)  (注意:由于HashMap的容量必须为2的N次方,故此时HashMap的实际容量为256)
如果实际容量为100,加载因子1,则计算工式为:(int) (100 / 1) + 1 = 101,则则实例化HashMap为 new HashMap<>(101, 1)   (注意:由于HashMap的容量必须为2的N次方,故此时HashMap的实际容量为128)
HashMap、HashMap加载因子0.75,初始容量16,扩容增量为原来的1倍
注意:加载因子越大节省内存但查找效率低,加载因子越小耗内存但查找效率高,系统默认加载因子为0.75,一般情况下我们是无需修改的。

//以下为计算HashMap的实际容量

//计算容量。
int capacity = (int) (realSize / loadFactor) + 1;
//必须为2的N次方并进行上舍入。
int pow = (int)Math.ceil( Math.log(capacity) / Math.log(2.0));
//返回2的N次方为实际容量。
return (int) Math.pow(2, pow);

以上单元测试HashMap、ArrayList持续增加元素及扩容情况:

    @Test
    public void testHashMapResize() throws Exception {
        System.out.println("-------- 开始测试HashMap --------");
        System.out.println("不设置 initCapacity");
        this.testHashMapResizeProfile(0);
        System.out.println("");
        System.out.println("initCapacity 为 25");
        this.testHashMapResizeProfile(25);
        System.out.println("");
        System.out.println("initCapacity 为 34");
        this.testHashMapResizeProfile(34);

        System.out.println();
        System.out.println("-------- 开始测试ArrayList --------");
        System.out.println("不设置 initCapacity");
        this.testArrayListResizeProfile(0);
        System.out.println("");
        System.out.println("initCapacity 为 25");
        this.testArrayListResizeProfile(25);
    }

    /**
     * 以循环添加25个元素测试扩容。
     * @param initCapacity 初始容量
     * @throws Exception
     */
    private void testHashMapResizeProfile(int initCapacity) throws Exception {
        Map<String, String> map = null;
        if (initCapacity <= 0) {
            map = new HashMap();
        } else {
            map = new HashMap(initCapacity);
        }

        Field threshold = map.getClass().getDeclaredField("threshold");
        Field size = map.getClass().getDeclaredField("size");
        Method capacity = map.getClass().getDeclaredMethod("capacity");

        threshold.setAccessible(true);
        size.setAccessible(true);
        capacity.setAccessible(true);

        // 临界值、容量测试
        for (int i = 1; i <= 25; i++) {
            map.put(String.valueOf(i), i + "**");
            System.out.println("第" + i + "个对象, size为" + size.get(map) + ", threshold为" + threshold.get(map) + ", capacity容量为" + capacity.invoke(map));
        }
    }

    /**
     * 以循环添加25个元素测试扩容。
     * @param initCapacity 初始容量
     * @throws Exception
     */
    private void testArrayListResizeProfile(int initCapacity) throws Exception {
        ArrayList<String> list = null;
        if (initCapacity <= 0) {
            list = new ArrayList();
        } else {
            list = new ArrayList(initCapacity);
        }

        Field size = list.getClass().getDeclaredField("size");
        Field elementData = list.getClass().getDeclaredField("elementData");

        size.setAccessible(true);
        elementData.setAccessible(true);

        // 临界值、容量测试
        for (int i = 1; i <= 25; i++) {
            list.add(String.valueOf(i));
            System.out.println("第" + i + "个对象, size为:" + size.get(list) + ", 扩容后容量为:" + ((Object[])elementData.get(list)).length);
        }
    }

以下为HashMap持续增加元素及扩容输出:

不设置 initCapacity
第1个对象, size为1, threshold为12, capacity容量为16
第2个对象, size为2, threshold为12, capacity容量为16
第3个对象, size为3, threshold为12, capacity容量为16
第4个对象, size为4, threshold为12, capacity容量为16
第5个对象, size为5, threshold为12, capacity容量为16
第6个对象, size为6, threshold为12, capacity容量为16
第7个对象, size为7, threshold为12, capacity容量为16
第8个对象, size为8, threshold为12, capacity容量为16
第9个对象, size为9, threshold为12, capacity容量为16
第10个对象, size为10, threshold为12, capacity容量为16
第11个对象, size为11, threshold为12, capacity容量为16
第12个对象, size为12, threshold为12, capacity容量为16
第13个对象, size为13, threshold为24, capacity容量为32
第14个对象, size为14, threshold为24, capacity容量为32
第15个对象, size为15, threshold为24, capacity容量为32
第16个对象, size为16, threshold为24, capacity容量为32
第17个对象, size为17, threshold为24, capacity容量为32
第18个对象, size为18, threshold为24, capacity容量为32
第19个对象, size为19, threshold为24, capacity容量为32
第20个对象, size为20, threshold为24, capacity容量为32
第21个对象, size为21, threshold为24, capacity容量为32
第22个对象, size为22, threshold为24, capacity容量为32
第23个对象, size为23, threshold为24, capacity容量为32
第24个对象, size为24, threshold为24, capacity容量为32
第25个对象, size为25, threshold为48, capacity容量为64
注意:扩容2次

initCapacity 为 25
第1个对象, size为1, threshold为24, capacity容量为32
第2个对象, size为2, threshold为24, capacity容量为32
第3个对象, size为3, threshold为24, capacity容量为32
第4个对象, size为4, threshold为24, capacity容量为32
第5个对象, size为5, threshold为24, capacity容量为32
第6个对象, size为6, threshold为24, capacity容量为32
第7个对象, size为7, threshold为24, capacity容量为32
第8个对象, size为8, threshold为24, capacity容量为32
第9个对象, size为9, threshold为24, capacity容量为32
第10个对象, size为10, threshold为24, capacity容量为32
第11个对象, size为11, threshold为24, capacity容量为32
第12个对象, size为12, threshold为24, capacity容量为32
第13个对象, size为13, threshold为24, capacity容量为32
第14个对象, size为14, threshold为24, capacity容量为32
第15个对象, size为15, threshold为24, capacity容量为32
第16个对象, size为16, threshold为24, capacity容量为32
第17个对象, size为17, threshold为24, capacity容量为32
第18个对象, size为18, threshold为24, capacity容量为32
第19个对象, size为19, threshold为24, capacity容量为32
第20个对象, size为20, threshold为24, capacity容量为32
第21个对象, size为21, threshold为24, capacity容量为32
第22个对象, size为22, threshold为24, capacity容量为32
第23个对象, size为23, threshold为24, capacity容量为32
第24个对象, size为24, threshold为24, capacity容量为32
第25个对象, size为25, threshold为48, capacity容量为64
注意:扩容1次

initCapacity 为 34   (int) (25 / 0.75) + 1 = 34
第1个对象, size为1, threshold为48, capacity容量为64
第2个对象, size为2, threshold为48, capacity容量为64
第3个对象, size为3, threshold为48, capacity容量为64
第4个对象, size为4, threshold为48, capacity容量为64
第5个对象, size为5, threshold为48, capacity容量为64
第6个对象, size为6, threshold为48, capacity容量为64
第7个对象, size为7, threshold为48, capacity容量为64
第8个对象, size为8, threshold为48, capacity容量为64
第9个对象, size为9, threshold为48, capacity容量为64
第10个对象, size为10, threshold为48, capacity容量为64
第11个对象, size为11, threshold为48, capacity容量为64
第12个对象, size为12, threshold为48, capacity容量为64
第13个对象, size为13, threshold为48, capacity容量为64
第14个对象, size为14, threshold为48, capacity容量为64
第15个对象, size为15, threshold为48, capacity容量为64
第16个对象, size为16, threshold为48, capacity容量为64
第17个对象, size为17, threshold为48, capacity容量为64
第18个对象, size为18, threshold为48, capacity容量为64
第19个对象, size为19, threshold为48, capacity容量为64
第20个对象, size为20, threshold为48, capacity容量为64
第21个对象, size为21, threshold为48, capacity容量为64
第22个对象, size为22, threshold为48, capacity容量为64
第23个对象, size为23, threshold为48, capacity容量为64
第24个对象, size为24, threshold为48, capacity容量为64
第25个对象, size为25, threshold为48, capacity容量为64
注意:未扩容

以下为ArrayList持续增加元素及扩容输出:

不设置 initCapacity
第1个对象, size为:1, 扩容后容量为:10
第2个对象, size为:2, 扩容后容量为:10
第3个对象, size为:3, 扩容后容量为:10
第4个对象, size为:4, 扩容后容量为:10
第5个对象, size为:5, 扩容后容量为:10
第6个对象, size为:6, 扩容后容量为:10
第7个对象, size为:7, 扩容后容量为:10
第8个对象, size为:8, 扩容后容量为:10
第9个对象, size为:9, 扩容后容量为:10
第10个对象, size为:10, 扩容后容量为:10
第11个对象, size为:11, 扩容后容量为:15
第12个对象, size为:12, 扩容后容量为:15
第13个对象, size为:13, 扩容后容量为:15
第14个对象, size为:14, 扩容后容量为:15
第15个对象, size为:15, 扩容后容量为:15
第16个对象, size为:16, 扩容后容量为:22
第17个对象, size为:17, 扩容后容量为:22
第18个对象, size为:18, 扩容后容量为:22
第19个对象, size为:19, 扩容后容量为:22
第20个对象, size为:20, 扩容后容量为:22
第21个对象, size为:21, 扩容后容量为:22
第22个对象, size为:22, 扩容后容量为:22
第23个对象, size为:23, 扩容后容量为:33
第24个对象, size为:24, 扩容后容量为:33
第25个对象, size为:25, 扩容后容量为:33
注意:扩容2次
initCapacity 为 25
第1个对象, size为:1, 扩容后容量为:25
第2个对象, size为:2, 扩容后容量为:25
第3个对象, size为:3, 扩容后容量为:25
第4个对象, size为:4, 扩容后容量为:25
第5个对象, size为:5, 扩容后容量为:25
第6个对象, size为:6, 扩容后容量为:25
第7个对象, size为:7, 扩容后容量为:25
第8个对象, size为:8, 扩容后容量为:25
第9个对象, size为:9, 扩容后容量为:25
第10个对象, size为:10, 扩容后容量为:25
第11个对象, size为:11, 扩容后容量为:25
第12个对象, size为:12, 扩容后容量为:25
第13个对象, size为:13, 扩容后容量为:25
第14个对象, size为:14, 扩容后容量为:25
第15个对象, size为:15, 扩容后容量为:25
第16个对象, size为:16, 扩容后容量为:25
第17个对象, size为:17, 扩容后容量为:25
第18个对象, size为:18, 扩容后容量为:25
第19个对象, size为:19, 扩容后容量为:25
第20个对象, size为:20, 扩容后容量为:25
第21个对象, size为:21, 扩容后容量为:25
第22个对象, size为:22, 扩容后容量为:25
第23个对象, size为:23, 扩容后容量为:25
第24个对象, size为:24, 扩容后容量为:25
第25个对象, size为:25, 扩容后容量为:25
注意:没有扩容