Java各个集合类的扩容机制

Java 中提供了很多的集合类,诸如map 、list、set等等。他们的扩容机制不尽相同。下边分别介绍一下。

List

ArrayList

 ArrayList以数组的形式存储。 ArrayList有与容量相关的构造器有两个,一个是ArrayList(int initialCapacity), 另外一个是ArrayList(),前者没有指定容量的大小,在初始创建的时候容量是0,在第一扩容的时候扩到10。第二次扩容的时候为1.5倍(newCapacity = oldCapacity + (oldCapacity >> 1);的速度递增(0、10、15、22、33、49.....)。而且每次都是在插入之前检查容量是否足够,如果不够才进行扩容扩容。因此他的加载因子是100%。

LinkedList

    链表结构,且是是双向链表, 不涉及扩容的问题。

Vector

   Vector与ArrayList一样,是存储在数组结构中。  与扩容机制相关的构造器有三个,分别是

  1. Vector(int initialCapacity, int capacityIncrement),
  2. Vector(int initialCapacity)
  3. Vector()

    其实这后两个最终都是调用了第一个构造器,不过是使用了不同的默认参数,initialCapacity是初始容量,默认是10,capacityIncrement 是每次扩容时候的递增数量,如果该数值不等于0则每次扩容的时候是原来的二倍,如果该数值大于0,则每次增长的数量等于该数值(

int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                 capacityIncrement : oldCapacity);
)。

  比如:

       Vector<String> v = new Vector<String>(); // 10 20 ,40 80 ,160,320 的速度递增

      Vector<String> v2 = new Vector<>(5,3);// 5 8 11 14 17 ,20,23 的速度递增。

   他的加载因子也是10

Stack

  继承于Vector,所以他的扩容机制等同于Vector的默认情况,也就是2倍速度扩容,加载因子为1

 

Map

hashtable

以hash桶数组的形式存储数据。他的构造器也是有多个,代码如下

public Hashtable() {
    this(11, 0.75f);
}

由此可以得知他的默认容量是11,而加载因子是0.75.  每次插入新的数据(不包括替换)之前需要判断是否达到扩容的阈值,如果已经达到则先进行扩容,并且按照新的结构排列原有的元素,然后插入元素,hashtable尤其需要注意的是不能插入key或value为空的键值对。插入新的元素的时候,元素的寻址方式是 (hash & 0x7FFFFFFF) % tab.length;  (hash & 0x7FFFFFFF) 的作用是保证这部分的数据是正数,(hash & 0x7FFFFFFF) % tab.length的作用是保证位置一定是落在该数组的索引范围内。如果引起hash冲突的情况下,该数组的索引位置存放多个元素,这些元素以链表的形式存储。

注意hashtable 是线程安全的。

HashMap

 HashMap的存储结构与hashtable基本一致。HashMap提供了多个构造器,但是最典型的是

public HashMap()  // 这个没有指定容量和加载因子,在初始状态下容量是0(存放数据的数组是空),在增加第一个元素之前容量为16,加载因子是0.75

public HashMap(int initialCapacity, float loadFactor) // 可以指定加载银子以及初始容量。

插入数据的的寻址方式:  (n - 1) & hash  保证一定是落在数组索引取值范围内。

哈希冲突的解决方式:增加数据的时候,如果key的哈希值相同,则保存在同一个桶内,存储方式要看此时桶内的数据量,如果桶内的数据量大于8,则用红黑树的方式存储。否则使用链表的形式存储。 在删除数据的时候,如果数据少于6个了,则把红黑树转换成链表的形式。插入一个新的数据后,如果达到扩容阈值,则调用resize()函数进行扩容。

Set

  关于set,因为他们都是基于对应的map实现的,所以扩容机制与对应的map保持一致,这里不再赘述。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值