-
首先 LinkedList 继承了 AbstractSequentialList,ArrayList 和Vector 都继承了AbstractList
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>
因为所以说LinkedList 具有链表和双向队列的特性。但是他没有实现 RandomAccess, 而ArrayList, Vector 都实现了RandomAcess
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess
所以ArrayList 和Vector 支持快速随机访问。但是因为内部存储使用的是
Vector:
protected Object[] elementData;
ArrayList:
transient Object[] elementData;
那么为什么Vector 和ArrayList 都 implement java.io.Serializable, 但是Vector 就序列化了数组元素,但是ArrayList 并没有,原因在于elementData是一个缓存数组,他会多余出一些没用的容量,等容量不够时再进行扩充容量,那么这些多余的容量,序列化时,就会产生浪费。ArrayList通过writeObject 和readObject 方法将缓存数组中的元素转换成流来解决这个问题。
-
然后我们再看一看他们都有什么方法。
增加:
Vector: 利用的数组的那一套,比如插入指定的下标
public synchronized void insertElementAt(E obj, int index) { modCount++; if (index > elementCount) { throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount); } ensureCapacityHelper(elementCount + 1); System.arraycopy(elementData, index, elementData, index + 1, elementCount - index); //把对象添加元素下标 elementData[index] = obj; elementCount++; }
但是直接如果直接加载后面的话还是挺快捷的
public synchronized void addElement(E obj) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = obj; }
ArrayList: 直接添加指定下标,跟Vector 一样换汤不换药。
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++; }
直接在后面添加:
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true;
唯一不同的是,他的直接添加的方法有返回值,返回成功失败的结果。
LinkedList: 添加指定下标会先做判断,判断下标是否与现有的链表的size 相同。
public void add(int index, E element) { checkPositionIndex(index); if (index == size) linkLast(element); else linkBefore(element, node(index)); }
LinkedList无需提前指定容量,因为基于链表操作,集合的容量随着元素的加入自动增加。
删除:删除时, Vector 和ArrayList 基于数组的方式进行删除, 但是Vector 的方法都是加入synchronized关键字的。
LinkedList: 使用unlink 方法对元素进行移除
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) {// 如果prev 为空,则给定节点为头节点 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 的一个意思, 直接返回数组对应下标
E elementData(int index) { return (E) elementData[index]; }
LinkedList: 对比Vector,ArrayList 来说,查找没有他们方便。
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,ArrayList,Vector的存储性能和特性
最新推荐文章于 2024-06-15 08:15:00 发布