




Arrays的copyOf()方法传回的数组是新的数组对象,改变传回数组中的元素值,不会影响原来的数组。
copyOf()的第二个自变量指定要建立的新数组长度,如果新数组的长度超过原数组的长度,则填充类型默认值,String类型填充null。int类型填充0

比如有下面这样一个数组我需要在index 5的位置去新增一个元素A

复制了一个数组,是从index 5的位置开始的,然后把它放在了index 5+1的位置

给我们要新增的元素腾出了位置,然后在index的位置放入元素A就完成了新增的操作了


我们现在要删除下面这个数组中的index5这个位置

那代码他就复制一个index5+1开始到最后的数组,然后把它放到index开始的位置

index5的位置就成功被”删除“了其实就是被覆盖了,给了你被删除的感觉。

按着上图示例:
index = 4,size = 9;
numMoved = 9-4-1;//4
也就是从index+1位置开始拷贝,拷贝4个元素,至index位置上。从元素5开始往后拷贝4个元素。
最后最后一个元素手动置为null,size–

public boolean add(E e) {
return map.put(e, PRESENT)==null;// 调用HashMap的put方法,PRESENT是一个至始至终都相同的虚值
}
| ArrayList | LinkedList | |
|---|---|---|
| 是否保证线程安全 | 线程不安全 | 线程不安全 |
| 底层 | 数组 | 双向链表 |
| 插入和删除是否受元素位置的影响 | ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e)方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element))时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 | LinkedList 采用链表存储,所以,如果是在头尾插入或者删除元素不受元素位置的影响(add(E e)、addFirst(E e)、addLast(E e)、removeFirst() 、 removeLast()),时间复杂度为 O(1),如果是要在指定位置 i 插入和删除元素的话(add(int index, E element),remove(Object o)), 时间复杂度为 O(n) ,因为需要先移动到指定位置再插入。 |
| 是否支持快速随机访问 | ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法) | 不支持 |
Array 可以包含基本类型和对象类型,ArrayList 只能包含对象类型。
Array 大小是固定的,ArrayList 的大小是动态变化的。
是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。
例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast机制。
原因:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
解决办法:
ArrayList 内容来源:https://blog.csdn.net/qq_35190492/article/details/103883964
ArrayList源码分析参考:https://blog.csdn.net/lkp1603645756/article/details/81264257