java.util 的各个 Collection
https://blog.csdn.net/anyoneking/article/details/1567808
https://www.cnblogs.com/myseries/p/7508110.html
ArrayList 底层是数组,
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
ArrayList 每增加一个元素,都是下标加1的地方 赋值为 该元素。
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
每查询一个元素,都是传入下标,然后直接到 数组里面找 元素。
E elementData(int index) {
return (E) elementData[index];
}
每删除一个元素,需要操作的数据比较多;如果删除的是ArrayList的第一个元素,那么所有后面的元素 都需要移动位置(向前移动一格)。
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
* @param src the source array.
* @param srcPos starting position in the source array.
* @param dest the destination array.
* @param destPos starting position in the destination data.
* @param length the number of array elements to be copied.
* @exception IndexOutOfBoundsException if copying would cause
* access of data outside array bounds.
* @exception ArrayStoreException if an element in the <code>src</code>
* array could not be stored into the <code>dest</code> array
* because of a type mismatch.
* @exception NullPointerException if either <code>src</code> or
* <code>dest</code> is <code>null</code>.
*/
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
ArrayList 底层是链表,先看网址的链表结构:
https://www.cnblogs.com/beppezhang/p/6564633.html
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* Links e as last element.
*/
void linkLast(E e) {
final Node<E> l = last;
//新元素作为最后一个元素,新元素的prev指向原来的最后一个元素;最后一个元素的next为null
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
//原来的list为空,则新元素既是第一个元素,也是最后一个元素
first = newNode;
else
//原来的list非空,则原来的新元素的next指向新插入的元素
l.next = newNode;
size++;
modCount++;
}
add方法,在不指明插入位置的情况下,默认将元素插入list的最后。
linkedList的get方法,就比较消耗时间
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
//使用了二分法查找,如果index在list的前面一半,从first开始查找;否则从last开始查找
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
linkedList的remove方法,修改指向 即可
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
//逻辑是将上一个元素的next指向删除元素的下一个元素,将下一个元素的prev指向删除元素的上一个元素
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
Vector就不展开了,与Arraylist的区别 就是加了同步synchronized的功能。
Arraylist和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加插入元素,都允许直接序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以插入数据慢,查找有下标,所以查询数据快,Vector由于使用了synchronized方法-线程安全,所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项前后项即可,插入数据较快。
再看stack, stack继承的Vector, 所以底层也是 数组结构
参考网址: https://www.cnblogs.com/zj0208/p/6296709.html
将数据 压入栈:
public E push(E item) {
addElement(item);
return item;
}
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
//将数组的最后一个字段的值 置为 新增的值
elementData[elementCount++] = obj;
}
peek方法获取栈顶元素,但并不移除,如果是空栈,会抛出异常:EmptyStackException。
栈顶元素 对于数组来说,是数组的末尾元素。
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
// pop方法移除并返回栈顶元素,如果是空栈,会抛出异常:EmptyStackException(pop
方法 效率低,因为有 System.arraycopy(elementData, index + 1, elementData, index, j); 动作
)
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
queue队列(太多了, 进入下一章):
https://www.cnblogs.com/lemon-flm/p/7877898.html
java.util.concurrent
每个线程安全类的底层实现 做分类
https://blog.csdn.net/lh87522/article/details/45973373
https://blog.csdn.net/windsunmoon/article/details/36903901
java.util.concurrent.atomic
每个线程安全类的底层实现 使用CAS吗?
java.util.concurrent.locks?
看可重入锁, 读写锁