java util包学习(6) LinkedLIst 源码分析
2013-10-28 23:44
295 查看
重点就是LinkedList 先看看Deque双端对列接口
不难吧,,看看后面的实现类吧
LinkedList的实现使用的是双向循环链表,,静态内部类作为节点实现 最重要的其实是迭代器的实现 这也是设计模式的一个要点 虽然没有学习过,,还有一个很重要的问题,链表的迭代器是快速失败的,这是为何呢?我们知道其实,,很容易,快速失败的原因就是它继承了
package java.util; public interface Deque<E> extends Queue<E> { void addFirst(E e); void addLast(E e); boolean offerFirst(E e); boolean offerLast(E e); E removeFirst(); E removeLast(); E pollFirst(); E pollLast(); E getFirst(); E getLast(); E peekFirst(); E peekLast(); boolean removeFirstOccurrence(Object o);//从此双端队列移除第一次出现的指定元素。 boolean removeLastOccurrence(Object o); boolean add(E e); boolean offer(E e); E remove(); E poll(); E element(); E peek(); void push(E e); E pop(); boolean remove(Object o); boolean contains(Object o); public int size(); Iterator<E> iterator(); Iterator<E> descendingIterator(); }
不难吧,,看看后面的实现类吧
package java.util; public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { private transient Entry<E> header = new Entry<E>(null, null, null);//使用的是内部类 头结点 双向链表实现 private transient int size = 0; public LinkedList() { header.next = header.previous = header;//初始化 } public LinkedList(Collection<? extends E> c) { this(); addAll(c); } public E getFirst() { if (size==0) throw new NoSuchElementException(); return header.next.element; } public E getLast() { if (size==0) throw new NoSuchElementException(); return header.previous.element; } public E removeFirst() { return remove(header.next); } public E removeLast() { return remove(header.previous); } public void addFirst(E e) { addBefore(e, header.next); } public void addLast(E e) { addBefore(e, header); } public boolean contains(Object o) { return indexOf(o) != -1; } public int size() { return size; } public boolean add(E e) { addBefore(e, header); return true; } public boolean remove(Object o) { if (o==null) { for (Entry<E> e = header.next; e != header; e = e.next) { if (e.element==null) { remove(e); return true; } } } else { for (Entry<E> e = header.next; e != header; e = e.next) { if (o.equals(e.element)) { remove(e); return true; } } } return false; } public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } public boolean addAll(int index, Collection<? extends E> c) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Object[] a = c.toArray(); int numNew = a.length; if (numNew==0) return false; modCount++; Entry<E> successor = (index==size ? header : entry(index)); Entry<E> predecessor = successor.previous; for (int i=0; i<numNew; i++) { Entry<E> e = new Entry<E>((E)a[i], successor, predecessor); predecessor.next = e; predecessor = e; } successor.previous = predecessor; size += numNew; return true; } public void clear() { Entry<E> e = header.next; while (e != header) { Entry<E> next = e.next; e.next = e.previous = null; e.element = null; e = next; } header.next = header.previous = header; size = 0; modCount++; } public E get(int index) { return entry(index).element; } public E set(int index, E element) { Entry<E> e = entry(index); E oldVal = e.element; e.element = element; return oldVal; } public void add(int index, E element) { addBefore(element, (index==size ? header : entry(index))); } public E remove(int index) { return remove(entry(index)); } private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; if (index < (size >> 1)) { for (int i = 0; i <= index; i++) e = e.next; } else { for (int i = size; i > index; i--) e = e.previous; } return e; } public int indexOf(Object o) { int index = 0; if (o==null) { for (Entry e = header.next; e != header; e = e.next) { if (e.element==null) return index; index++; } } else { for (Entry e = header.next; e != header; e = e.next) { if (o.equals(e.element)) return index; index++; } } return -1; } public int lastIndexOf(Object o) { int index = size; if (o==null) { for (Entry e = header.previous; e != header; e = e.previous) { index--; if (e.element==null) return index; } } else { for (Entry e = header.previous; e != header; e = e.previous) { index--; if (o.equals(e.element)) return index; } } return -1; } public E peek() { if (size==0) return null; return getFirst(); } public E element() { return getFirst(); } public E poll() { if (size==0) return null; return removeFirst(); } public E remove() { return removeFirst(); } public boolean offer(E e) { return add(e); } public boolean offerFirst(E e) { addFirst(e); return true; } public boolean offerLast(E e) { addLast(e); return true; } public E peekFirst() { if (size==0) return null; return getFirst(); } public E peekLast() { if (size==0) return null; return getLast(); } public E pollFirst() { if (size==0) return null; return removeFirst(); } public E pollLast() { if (size==0) return null; return removeLast(); } public void push(E e) { addFirst(e); } public E pop() { return removeFirst(); } public boolean removeFirstOccurrence(Object o) { return remove(o); } public boolean removeLastOccurrence(Object o) { if (o==null) { for (Entry<E> e = header.previous; e != header; e = e.previous) {//从后往前 if (e.element==null) { remove(e); return true; } } } else { for (Entry<E> e = header.previous; e != header; e = e.previous) { if (o.equals(e.element)) { remove(e); return true; } } } return false; } public ListIterator<E> listIterator(int index) { return new ListItr(index); } private class ListItr implements ListIterator<E> { private Entry<E> lastReturned = header; private Entry<E> next; private int nextIndex; private int expectedModCount = modCount; ListItr(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); if (index < (size >> 1)) { next = header.next; for (nextIndex=0; nextIndex<index; nextIndex++) next = next.next; } else { next = header; for (nextIndex=size; nextIndex>index; nextIndex--) next = next.previous; } } public boolean hasNext() { return nextIndex != size; } public E next() { checkForComodification(); if (nextIndex == size) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.element; } public boolean hasPrevious() { return nextIndex != 0; } public E previous() { if (nextIndex == 0) throw new NoSuchElementException(); lastReturned = next = next.previous; nextIndex--; checkForComodification(); return lastReturned.element; } public int nextIndex() { return nextIndex; } public int previousIndex() { return nextIndex-1; } public void remove() { checkForComodification(); Entry<E> lastNext = lastReturned.next; try { LinkedList.this.remove(lastReturned); } catch (NoSuchElementException e) { throw new IllegalStateException(); } if (next==lastReturned) next = lastNext; else nextIndex--; lastReturned = header; expectedModCount++; } public void set(E e) { if (lastReturned == header) throw new IllegalStateException(); checkForComodification(); lastReturned.element = e; } public void add(E e) { checkForComodification(); lastReturned = header; addBefore(e, next); nextIndex++; expectedModCount++; } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } private static class Entry<E> { E element;//数据域 Entry<E> next;//双向链表 Entry<E> previous; Entry(E element, Entry<E> next, Entry<E> previous) { this.element = element; this.next = next; this.previous = previous; } } private Entry<E> addBefore(E e, Entry<E> entry) { Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); newEntry.previous.next = newEntry;//修改指针域改两面的 newEntry.next.previous = newEntry; size++; modCount++; return newEntry; } private E remove(Entry<E> e) { if (e == header) throw new NoSuchElementException(); E result = e.element; e.previous.next = e.next; e.next.previous = e.previous; e.next = e.previous = null; e.element = null;//不需要e了 所以与它相关的指针域置为null size--; modCount++; return result; } public Iterator<E> descendingIterator() { return new DescendingIterator(); } private class DescendingIterator implements Iterator { final ListItr itr = new ListItr(size()); public boolean hasNext() { return itr.hasPrevious(); } public E next() { return itr.previous(); } public void remove() { itr.remove(); } } public Object clone() { LinkedList<E> clone = null; try { clone = (LinkedList<E>) super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } // Put clone into "virgin" state clone.header = new Entry<E>(null, null, null); clone.header.next = clone.header.previous = clone.header; clone.size = 0; clone.modCount = 0; // Initialize clone with our elements for (Entry<E> e = header.next; e != header; e = e.next) clone.add(e.element); return clone; } public Object[] toArray() { Object[] result = new Object[size]; int i = 0; for (Entry<E> e = header.next; e != header; e = e.next) result[i++] = e.element; return result; } public <T> T[] toArray(T[] a) { if (a.length < size) a = (T[])java.lang.reflect.Array.newInstance( a.getClass().getComponentType(), size); int i = 0; Object[] result = a; for (Entry<E> e = header.next; e != header; e = e.next) result[i++] = e.element; if (a.length > size) a[size] = null; return a; } private static final long serialVersionUID = 876323262645176354L; private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden serialization magic s.defaultWriteObject(); // Write out size s.writeInt(size); // Write out all elements in the proper order. for (Entry e = header.next; e != header; e = e.next) s.writeObject(e.element); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden serialization magic s.defaultReadObject(); // Read in size int size = s.readInt(); // Initialize header header = new Entry<E>(null, null, null); header.next = header.previous = header; // Read in all elements in the proper order. for (int i=0; i<size; i++) addBefore((E)s.readObject(), header); } }
LinkedList的实现使用的是双向循环链表,,静态内部类作为节点实现 最重要的其实是迭代器的实现 这也是设计模式的一个要点 虽然没有学习过,,还有一个很重要的问题,链表的迭代器是快速失败的,这是为何呢?我们知道其实,,很容易,快速失败的原因就是它继承了
AbstractList<E>类的modcount的字段,每修改集合时,就会发生变化,迭代器的快速失败原理就是要得到这个字段然后判断现在的modcount字段和开始初始化的modcount是否相等,相等才不会引发异常啊!!
相关文章推荐
- java util包学习(3) ArrayList LInkedList 分析
- Java集合源码学习笔记(三)LinkedList分析
- Java集合源码学习(三)LinkedList分析
- Java Collections Framework之Deque(LinkedList实现)源码分析(基于JDK1.6)(已补充)
- java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析
- java源码分析之LinkedList
- Java中arraylist和linkedlist源码分析与性能比较
- Java集合:LinkedList使用详解及源码分析
- java util包学习(5) Vector 源码分析
- (8) Java源码分析 ---- LinkedList (对应数据结构中线性表中的双向循环链表,JDK1.6)
- 源码分析:LinkedList和Java中的指针操作
- java util包学习(9)HashMap源码分析
- java1.8 常用集合源码学习:LinkedList
- Java 集合框架源码分析(二)——LinkedList
- Java基础——LinkedList源码分析
- 分析Java中ArrayList与LinkedList列表结构的源码
- java源码分析之LinkedList
- JDK源码分析(2)-java.util.LinkedList
- 数据结构与算法学习(二)链式存储结构LinkedList源码分析
- java容器源码分析--LinkedList(JDK1.8)