概述
在学习和面试中,经常会遇到关于集合内存的问题,我以一个初学者的身份,分析一下关于各个类型集合的内存的变化。
集合的顶层接口为Collection和Map,而Collection则有两个子接口,分别是List和Set,其中List为有序接口;Set为无序接口。List中常用的集合为ArrayList,Vector;Set中常用的为HashSet。Map中常用的有HashMap和Hashtable。
因本文主要描述内存的问题,因此不过多描述各类集合之间的区别。
ArrayList
ArrayList为有序的集合,他的底层数据结构是数组,默认初始容量为10。也就是说,在创建出一个ArrayList集合,且不定大小时,会创建一个大小为10的数组作为容器。在往集合添加元素时会进行判断,容量是否已经满了,如果装满了,ArrayList的容量会扩大为原来的1.5倍,实际上是创建一个新的数组,容量为原来的1.5倍,然后将原数组中的元素依次放置到数组中。
Vector
Vector也是有序的集合,底层也同样是数组,默认的初始容量也是10。他与ArrayList的不同点在于,Vector在容量装满时容量变化为原来的2倍。
HashMap

HashMap是AbstracMap的子类,Map的实现类,他存储数据是基于数组和链表实现的。在储存数据时,首先会调用hashcode()方法根据他的key值计算出一个哈希码,再使用这个哈希码对数组长度取模,得出的值存在在数组中,如果得出的值已经存在,则会判断value是否相等,如果相等则覆盖,如果不相等则将数据储存在该位置延伸出来的链表上。
HashMap的默认初始长度为16,负载因子为0.75,当数组的内容达到长度的75%时,数组就会进行扩容,达到原来的两倍。他在扩容是同样是创建一个新的两倍长度的数组,然后将原来的元素的hashcode按新的数组长度取模,放置在数组或链表上。
Hashtable
Hashtable是Dictionary的子类,Map的实现类,他储存数据的原理与HashMap相同,不同的是,Hashtable的默认初始长度为11,负载因子也为0.75。
HashSet
HashSet的底层储存实际上是依靠HashMap实现的,HashSet储存的key,将key的Hashcode对数组长度取模放置在相应位置,当有相同的值时就覆盖,所以HashSet是无序且元素无法重复的。HashSet的初始长度为16,负载因子0.75。
负载因子
最后再提一下负载因子。负载因子相当于一个阈值,当数组的内容达到这个阈值,即内容>=负载因子×数组长度时,发生扩容。负载因子设置越高,对数组的利用就会越高,链表的长度就会越长,查询的效率就会越低,一般情况使用默认的0.75。
以上就是全部内容,敬请批评指正。
本文深入解析了Java中集合类如ArrayList、Vector、HashMap、Hashtable及HashSet的内存管理机制,包括它们的底层数据结构、扩容策略及负载因子的影响。
4832

被折叠的 条评论
为什么被折叠?



