LinkedList 大家都不陌生,来看看他的实现原理,首先声明,他是一个双链条,即previous,next
/**
* Constructs a new empty instance of {@code LinkedList}.
*/
public LinkedList() {
voidLink = new Link<E>(null, null, null);
voidLink.previous = voidLink;
voidLink.next = voidLink;
}
默认无参构造方法中,新建了一个空节点,他的previous,next都 指向他自己。另外一个构造方法:
/**
* Constructs a new instance of {@code LinkedList} that holds all of the
* elements contained in the specified {@code collection}. The order of the
* elements in this new {@code LinkedList} will be determined by the
* iteration order of {@code collection}.
*
* @param collection
* the collection of elements to add.
*/
public LinkedList(Collection<? extends E> collection) {
this();
addAll(collection);
}
默认添加节点的位置是在最后:
/**
* Adds the specified object at the end of this {@code LinkedList}.
*
* @param object
* the object to add.
* @return always true
*/
@Override
public boolean add(E object) {
return addLastImpl(object);
}
private boolean addLastImpl(E object) {
Link<E> oldLast = voidLink.previous;
Link<E> newLink = new Link<E>(object, oldLast, voidLink);
voidLink.previous = newLink;
oldLast.next = newLink;
size++;
modCount++;
return true;
}
其中链条的设置顺序为:
1.先设置新添加的节点的previous,next
2.然后设置老节点的next,和空节点的previous,完成节点链条的设置值。
3.总大小自增,修改次数自增
属性modCount的作用在于:
当你在遍历整个list列表数据时,如果异步线程修改了这个列表的数据时,这个list遍历过程能够及时的抛错并退出当前的遍历,可以很好的保护数据读取的一致性。private class SimpleListIterator implements Iterator<E> { int pos = -1; int expectedModCount; int lastPosition = -1; SimpleListIterator() { expectedModCount = modCount; } public boolean hasNext() { return pos + 1 < size(); } public E next() { if (expectedModCount == modCount) { try { E result = get(pos + 1); lastPosition = ++pos; return result; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } throw new ConcurrentModificationException(); } public void remove() { if (this.lastPosition == -1) { throw new IllegalStateException(); } if (expectedModCount != modCount) { throw new ConcurrentModificationException(); } try { AbstractList.this.remove(lastPosition); } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } expectedModCount = modCount; if (pos == lastPosition) { pos--; } lastPosition = -1; } }
如果我们要移除一部分数据时:
/**
* Removes the object at the specified location from this {@code LinkedList}.
*
* @param location
* the index of the object to remove
* @return the removed object
* @throws IndexOutOfBoundsException
* if {@code location < 0 || location >= size()}
*/
@Override
public E remove(int location) {
if (location >= 0 && location < size) {
Link<E> link = voidLink;
if (location < (size / 2)) {
for (int i = 0; i <= location; i++) {
link = link.next;
}
} else {
for (int i = size; i > location; i--) {
link = link.previous;
}
}
Link<E> previous = link.previous;
Link<E> next = link.next;
previous.next = next;
next.previous = previous;
size--;
modCount++;
return link.data;
}
throw new IndexOutOfBoundsException();
}
移除数据相对比较简单:
1.定位移除节点的位置
2.上一节点的next 设值
3.下一节点的previous 设值
相关的方法: removeFirstImpl,removeLastImpl
其中里面有一个关键字:transient