JAVA集合面面观
Posted ywd979
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA集合面面观相关的知识,希望对你有一定的参考价值。
List的常用实现:vector,ArrayList,linkedList。
总体关系如下(java8):
vector和arraylist
两者底层都是采用数组的形式。但是有些许不同
// ArrayList
transient Object[] elementData; // non-private to simplify nested class access
// vector
protected Object[] elementData;
- 在序列化的时候,arraylist将会调用writeObject和readObject方法来序列化。所以比vector在序列化上更安全。
- 其次,vector的主要元素操作方法都是synchronize修饰的来保证线程安全。(现在基本抛弃vector。代替Collections.synchronizeList的方法来构造线程安全)
- vector的构造函数允许扩展的步长。
arraylist和linkedlist
arraylist底层是数组实现
linkedlist是链式的线性表,也是双向链表,因为从上图可以看到它还实现了Deque,可以用做双端队列,或者栈使用。
arraylist是数组实现,所以对于修改List的操作,会进行整体的搬家。
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;
}
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
可以看出,对于修改数据的操作,会非常重。但是相对于get将非常快。直接操作下标获取。
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
linkedlist,由内部类node实现。有前后节点组成双向链表
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
看实现可以知道。当修改元素的时候,只需要修改节点对应的前节点和后节点就能完成插入。
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
然后看get, 需要从头或者从末开始遍历。
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
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实现了Deque。提供的几个方法,所以可以作为队列使用。
// 待续
以上是关于JAVA集合面面观的主要内容,如果未能解决你的问题,请参考以下文章