没错,长大是一件扫兴的事情
越长大,就越清晰的感觉到生活的坚硬、现实的功利、交际的笨拙;
也越发有‘我已泯然众人矣’的伤感,和‘我还能怎样’的无奈;
概括起来就是说:这世间并不适宜人。
ArrayList源码分析
以下内容基于azul-jdk11版本
类图
RandomAccess、Serializable是标志接口,分别代表实现类支持快速随机访问、网络传输特性。
ArrayList和LinkedList区别
1. 数据结构上:前者基于数组实现,后者1.6通过双向循环链表,1.7取消了循环,改为双向链表
2. 查询效率上:前者支持随机访问,时间复杂度O(1),后者需要按照指针一个个等值匹配,时间复杂度为O(n),n代表链表长度
3. 写入效率上:前者在add(E e)方法时,将元素添加到数组尾部,时间复杂度为O(1),在add(int index, E e)时间复杂度是O(n-1),因为在进行add/remove时,需要将从索引位置到数组长度的元素向后/向前移动一位;后者在add(E e)时间复杂度为O(1),在add(int index, E e)时间复杂度为O(n),因为需要先遍历找到插入的元素
4. 存储空间上:前者在初始化/扩容时都会预留一部分空间,后者在每个元素上增加了前后元素的地址指针
构造方法
以下三种构造方法,实际可以大致理解为懒初始化,优先默认空数组作为初始值~
扩容逻辑
新增元素时会比较数组是否为空数组,如果为空数组,则将数组长度设置为10
第一次添加元素时,因为是一个空数组,所以走入到了grow中,然后调用newCapacity方法进行初始化空间,此时minCapacity=1,因为oldCapacity=0,故而获取到需要扩容的容量为10,最终使用Arrays.copyOf方法将原数组容量扩容至10,在后续的超过默认10容量时,会依据右移动也就是1.5倍进行容量增加;
确保容量方法做嘛用的
此方法可以在大量插入时使用,避免数组多次扩容造成性能损失,一次性预定存储空间
5月步一期望
看到这里的筒子可以发问一波,甭管是关于文章的,或者是历来面试题都可~互相重踩~