Bootstrap

集合底层原理

1.ArrayList
ArrayList的底层其实是一个数组
当调用其无参构造的时候,底层会创建出一个空的数组。
当有第一个元素添加进来的时候,会创建一个默认大小为10 的数组。
扩容机制:
当数组已满的时候,会创建一个容量为旧数组容量的1.5倍大小的新数组,并将旧数组的数据复制到新数组中。
扩容的过程中还有如下两种特殊情况:
(1)如果扩大1.5倍新数组还是放不下的话,会根据实际大小创建出一个实际所需的最小容量的新数组。
(2) 当所需容量超过ArrayList的最大容量时,会调用一个hugeCapacity方法。在hugeCapacity方法中,它先对minCapacity进行了判断,如果minCapacity小于0,则抛出OutOfMemoryError异常。若不满足条件,就比较minCapacity和MAX_ARRAY_SIZE的大小,若大于,就返回Integer的最大值(0x7fffffff),若不大于,则返回MAX_ARRAY_SIZE。
这解释一下为什么MAX_ARRAY_SIZE=Integer.MAX_VALUE - 8。
在源码中的注解上有提到:
要分配的数组的最大大小。有些虚拟机在数组中保留一些header word。尝试分配更大的数组可能会导致OutOfMemoryError:请求的数组大小超过虚拟机限制.
2,hashset
(1) JDK 8之前
在JDK把之前hashset采用的是数组加链表的形式。
首先,在添加第一个元素的时候会创建一个长度为16,默认加载因子为0.75的数组。
接着,会 根据元素的哈希值对数组 的长度取余存入对应的位置。
接着,判断当前位置是否为null,如果为null就直接存入,
接着,如果不为null,就调用equals方法,如果相等就舍弃,如果不相等则存入数组
JDK8之前是新元素占用老元素的位置,老元素挂在新元素下面。

当数组元素的个数超过(长度*加载因子)的时候,就扩容。
(2) JDK 8之后
JDK8之后是新元素挂在老元素下面。并且如果链表长度大于8并且数组长度大于等于64的时候,链表会自动转为红黑树。

HashSet的无重复原则
JAVA中提供的数据类型( 8个基本数据类型+引用数据类型String),由于底层重写了equals()方法,比较方式由原来Object类中默认的“”方式,改成了 值比较的方式。所以,这里的9个数据类型,通过equals()方法进行的是值比较。
·而我们自己通过Class关键字定义的类所创建的类对象,是否相同是通过equals()方法(默认" == "的方式)进行比较的。由于equals()方法没有重写,内部默认的比较方式是 “
” ,所以默认比较的是对象的地址引用。
·综上所述,我们需要知道,若HashSet想要实现往里面添加的对象是不重复的,就需要重写equals()和hashCode()方法。
HashSet底层
HashSet的底层,是利用此HashMap的类对象map进行数据存储的
我们存入的所有元素都作为了HashMap中的键key,
而所有key对应的value值,存的都是这这Object类对象。

;