java list map 扩容_java集合的扩容机制 - 惊觉...

总结一:以下就是List下的三个实现类集合ArrayList 和Vector,LinkedList扩容总结:

ArrayList 和Vector扩容机制总结:

ArrayList 和Vector,底层都是Object数组,默认加载因子都是1(元素满了才扩展容量).默认容量都是10;但是ArrayList 在jdk1.8时默认为空,当添加元素时,才初始化为10个容量。ArrayList:新容量为原容量的1.5倍,Vector:新容量为原容量的2倍.

ArrayList 默认初始容量为10,(jdk8的时候底层Object[] elementData数组初始化为{},并没有创建长度为10的数组。在add元素时才创建了10个容量。)

线程不安全,查询速度快

底层数据结构是数组结构

扩容增量:原容量的 0.5倍,新容量为原容量的1.5倍。

如 ArrayList的容量为10,一次扩容后是容量为15

同样可以通过分析源码知道:

Vector:

默认初始容量为10,(jdk7和jdk8一样都初始容量为10)。

线程安全,但速度慢

底层数据结构是数组结构

加载因子为1:即当 元素个数 超过 容量长度 时,进行扩容

扩容增量:原容量的 1倍,新容量为原容量的2倍。

如 Vector的容量为10,一次扩容后是容量为20

LinkedList没有扩容机制:

LinkedList:没有扩容机制,因为其底层是双向链表结果。不存在数组的扩容一说,没有初始化大小,也没有扩容的机制,就是一直在前面或者后面新增就好。。

总结二:Set下的三个实现类集合HashSet和LinkedHashSet,TreeSet,扩容总结:LinkedHashSet,TreeSet没有数组的扩容机制。

HashSet和HashMap扩容机制总结:

HashSet和HashMap都是默认初始容量是16,加载因子是0.75,扩容为原来的2倍。而带LinkedHashSet和LinkedHashMap是链表不存在扩容的,HashSet:底层是数组+链表的结构。

Set(集) 元素无序的、不可重复。

HashSet:线程不安全,存取速度快

底层实现是一个HashMap(保存数据),HashSet:底层是数组+链表的结构,实现Set接口

默认初始容量为16(为何是16,见下方对HashMap的描述)

加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容

扩容增量:原容量的 1 倍,新容量为原容量的2倍。

如 HashSet的容量为16,一次扩容后是容量为32。

因为构造一个HashSet,其实相当于新建一个HashMap,然后取HashMap的Key。

扩容机制和HashMap一样。

Map是一个双列集合

HashMap:默认初始容量为16

(为何是16:16是2^4,可以提高查询效率,另外,32=16<<1 –>至于详细的原因可另行分析,或分析源代码)

加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容

扩容增量:原容量的 1 倍,新容量为原容量的2倍。

如 HashSet的容量为16,一次扩容后是容量为32

Hashtable扩容机制:

public Hashtable() {

this(11, 0.75f);

}

Hashtable默认初始容量11。

二、扩容加载因子(0.75),当超出默认长度(int)(11*0.75)=8时,扩容为oldx2+1。新容量为原容量的2倍+1.

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

小结:HashTable和HashMap区别

第一,继承不同。

public class Hashtable extends Dictionary implements Map

public class HashMap extends AbstractMap implements Map

第二:

Hashtable 中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用

Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

第三,Hashtable中,key和value都不允许出现null值。

在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,

即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中

是否存在某个键, 而应该用containsKey()方法来判断。

第四,两个遍历方式的内部实现上不同。

Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

第五,哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

第六,Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old2+1。HashMap中hash数组的默认大小是16, 增加的方式是 old2。

小结:StringBuffer和StringBuilder:

StringBuilder和StringBuffer的初始容量都是16,程序猿尽量手动设置初始值。以避免多次扩容所带来的性能问题,默认数组容量扩充为原数组容量的2倍+2。

1.StringBuilder是jdk1.5引进的,而StringBuffer在1.0就有了;

2.StringBuilder和StringBuffer都是可变的字符串。能够通过append或者insert等方法改动串的内容;

3.StringBuffer是线程安全的而StringBuilder不是,因而在多线程的环境下优先使用StringBuffer,而其它情况下推荐使用

StringBuilder,由于它更快。

4.StringBuilder和StringBuffer都继承自AbstractStringBuilder类,AbStractStringBuilder主要实现了扩容、append、

insert方法。StrngBuilder和StringBuffer的相关方法都直接调用的父类。

5.StringBuilder和StringBuffer的初始容量都是16,程序猿尽量手动设置初始值。以避免多次扩容所带来的性能问题;

6.StringBuilder和StringBuffer的扩容机制是这种:首先试着将当前数组容量扩充为原数组容量的2倍加上2,假设这个新容

量仍然小于预定的最小值(minimumCapacity),那么就将新容量定为(minimumCapacity),最后推断是否溢出,若溢出,

则将容量定为整型的最大值0x7fffffff。

转载自CSDN-专业IT技术社区

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页