Java 常用集合扩容机制总结

参考:java中各种集合的扩容机制记录总结_wwwtotoro的博客-CSDN博客_集合的扩容机制

JAVA中的部分需要扩容的内容总结如下:

第一部分:HashMap 、HashSet、Hashtable

第二部分:ArrayList、CopyOnWriteArrayList

第三部分:StringBuffer、StringBuilder

先从以下几个源码方面分析:(JDK1.8)

1、初始容量。2、扩容机制。3、同类型之间对比 4、最大容量

 

为什么要-8:

因为自己作为数组,除了存储数据本身以外,还需要32 bytes的大小来存储对象头信息。

Java每个对象都包含了对象头,HotSpot虚拟机中对象头的大小不会超过32 bytes,所以最大容量减8才不会溢出。

1.1 HashMap:

一、初始容量定义:默认为1 << 4(16)。最大容量为1<< 30

二、扩容加载因子为(0.75),第一个临界点在当HashMap中元素的数量大于table数组长度*加载因子(16*0.75=12),
则按oldThr << 1(原长度*2)扩容。

1.2 HashSet

一、初始容量定义:16。因为构造一个HashSet,其实相当于新建一个HashMap,然后取HashMap的Key。

扩容机制和HashMap一样。

1.3 Hashtable

一、初始容量定义:capacity (11)。

二、扩容加载因子(0.75),当超出默认长度(int)(11*0.75)=8时,扩容为old*2+1。

int newCapacity = (oldCapacity << 1) + 1;

2.1 ArrayList

一、初始容量定义:10。

二、扩容:oldCapacity + (oldCapacity >> 1),即原集合长度的1.5倍。


int newCapacity = (oldCapacity * 3)/2 + 1;
2.2 CopyOnWriteArrayList:

CopyOnWriteArrayList在做修改操作时,每次都是重新创建一个新的数组,在新数组上操作,最终再将新数组替换掉原数组。因此,在做修改操作时,仍可以做读取操作,读取直接操作的原数组。读和写操作的对象都不同,因此读操作和写操作互不干扰。只有写与写之间需要进行同步等待。另外,原数组被声明为volatile,这就保证了,一旦数组发生变化,则结果对其它线程(读线程和其它写线程)是可见的。

CopyOnWriteArrayList并不像ArrayList一样指定默认的初始容量。它也没有自动扩容的机制,而是添加几个元素,长度就相应的增长多少。CopyOnWriteArrayList适用于读多写少,既然是写的情况少,则不需要频繁扩容。并且修改操作每次在生成新的数组时就指定了新的容量,也就相当于扩容了,所以不需要额外的机制来实现扩容。

3.1 StringBuffer

一、初始容量定义:16。

二、扩容:因为StringBuffer extends AbstractStringBuilder,所以实际上是用的是AbstractStringBuilder
的扩容方法,当用append(str)添加字符串时,假设字符串中已有字符长度为count的字符串,初始长度value=16,若要添加的
字符串长度(count+str.length())<=(value*2+2)则按value*2+2长度扩容,并且value=value*2+2,若(count+str.length())>(value*2+2),则按count+str.length()长度扩容,并且value=count+str.length()。下次超出时再按以上方法与value*2+2比较扩容。

private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;

3.2 StringBuilder

public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
public StringBuilder() {
super(16);
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;

 

posted @ 2022-03-17 11:49  Nickeyhu  阅读(1259)  评论(0编辑  收藏  举报