前言
看了很多博客对于arraylist也只是停留在add remove上 只知道arraylist是个数组 里面装的是对象 知道有一天发现 在循环remove的时候删除的数据错误的 (二次循环过滤重复数据)后来用iterator来解决的 使用的很片面。
主题
首先ArrayList是非线程安全的 动态数组
1.线程不安全的原因
各类面试题一直说ArrayList线程不安全 但为什么线程不安全懵懵懂懂
如果两个线程同时add的时候 因为是数组 假如原来数组的长度为8 第一个线程增加一个为9 第二个线程增加一个也为9 同一时间增加了两个数据 会导致数组越界的情况 所以线程不安全
2. ArrayList的扩容策略
假如容量不够了 旧的容量加上旧的容量移位1
如果比最小的还要小 就置换
如果比最大的还要大 直接给一个int类型最大的数
这里有一个默认的属性DEFAULT_CAPACITY 也就是说 当第一次扩容时判断是空 首先默认为0 第一次扩容时候 有可能扩容的值为10 但如果需要的数量更大时则申请的是更大的容量
QQ截图20200703135402.pngArrayList的继承结构
QQ截图20200703102713.png1.AbstractList
抽象的list类 继承了AbstractCollection 实现了List接口 把各个接口里的内容重新抽取起来 abstract 重新再封装 (装饰模式)提供了add clear addAll等方法
QQ截图20200703111556.png这里倒是有个疑问 为什么AbstractList已经实现了List接口了 为什么ArrayList也要重新再实现一遍这个接口目的是为了什么?
1.虽然从语义上是冗余的,但设计是合理的 ArrayList作为一个对象首先符合List接口定义,基于接口开闭原则,将List的一些固定行为进行抽象使得ArrayList必须实现List中的所有方法
2. RandomAccess Cloneable java.io.Serializable
这两个接口是空接口实现的意义是什么呢?
RandomAccess在Collections里有大量的 instanceof这种
判断是否实现了这个接口 做一个区分
加快随机访问的速度
这里有人又要问 加快随机访问速度有啥用 为啥ArrayList有 LinkedList没有勒
int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
int low = 0;
int high = list.size()-1;
while (low <= high) {
int mid = (low + high) >>> 1;
Comparable<? super T> midVal = list.get(mid);
int cmp = midVal.compareTo(key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
}
如果是数组形式就while循环来查找 如果是其他形式就用迭代器的方式进行查找
Cloneable 作用 clone的时候需要这个接口
java.io.Serializable 支持序列化 可以进行intent传输 或者进程间的数据传输
ArrayList 初始化 add addAll remove removeAll 操作
初始化
这里默认是一个空数组
QQ截图20200703114436.png添加数据 扩容
QQ截图20200703114919.png之前用两层for循环去remove数据的时候总是出现各种各样的问题
因为是数组 如果正向删除的话会出现问题 或者用迭代删除
ArrayList的contains比较
/**
* Returns <tt>true</tt> if this list contains the specified element.
* More formally, returns <tt>true</tt> if and only if this list contains
* at least one element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* @param o element whose presence in this list is to be tested
* @return <tt>true</tt> if this list contains the specified element
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
* or -1 if there is no such index.
*/
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
ArrayList 对象比较
如果对象不为空则进入equals比较方法
如果对象为空的话 而且ArrayList里的每一项内容不为空的话 返回true
最后
希望先做一个初步总结,后续有时间在重新锊一遍代码
网友评论