📄 cursorablelinkedlist.java
字号:
protected Listable insertListable(Listable before, Listable after, Object value) { _modCount++; _size++; Listable elt = new Listable(before,after,value); if(null != before) { before.setNext(elt); } else { _head.setNext(elt); } if(null != after) { after.setPrev(elt); } else { _head.setPrev(elt); } broadcastListableInserted(elt); return elt; } /** * Removes the given * {@link org.apache.commons.collections.CursorableLinkedList.Listable} * from my list. */ protected void removeListable(Listable elt) { _modCount++; _size--; if(_head.next() == elt) { _head.setNext(elt.next()); } if(null != elt.next()) { elt.next().setPrev(elt.prev()); } if(_head.prev() == elt) { _head.setPrev(elt.prev()); } if(null != elt.prev()) { elt.prev().setNext(elt.next()); } broadcastListableRemoved(elt); } /** * Returns the * {@link org.apache.commons.collections.CursorableLinkedList.Listable} * at the specified index. * * @throws IndexOutOfBoundsException if index is less than zero or * greater than or equal to the size of this list. */ protected Listable getListableAt(int index) { if(index < 0 || index >= _size) { throw new IndexOutOfBoundsException(String.valueOf(index) + " < 0 or " + String.valueOf(index) + " >= " + _size); } if(index <=_size/2) { Listable elt = _head.next(); for(int i = 0; i < index; i++) { elt = elt.next(); } return elt; } else { Listable elt = _head.prev(); for(int i = (_size-1); i > index; i--) { elt = elt.prev(); } return elt; } } /** * Registers a {@link CursorableLinkedList.Cursor} to be notified * of changes to this list. */ protected void registerCursor(Cursor cur) { // We take this opportunity to clean the _cursors list // of WeakReference objects to garbage-collected cursors. for (Iterator it = _cursors.iterator(); it.hasNext(); ) { WeakReference ref = (WeakReference) it.next(); if (ref.get() == null) { it.remove(); } } _cursors.add( new WeakReference(cur) ); } /** * Removes a {@link CursorableLinkedList.Cursor} from * the set of cursors to be notified of changes to this list. */ protected void unregisterCursor(Cursor cur) { for (Iterator it = _cursors.iterator(); it.hasNext(); ) { WeakReference ref = (WeakReference) it.next(); Cursor cursor = (Cursor) ref.get(); if (cursor == null) { // some other unrelated cursor object has been // garbage-collected; let's take the opportunity to // clean up the cursors list anyway.. it.remove(); } else if (cursor == cur) { ref.clear(); it.remove(); break; } } } /** * Informs all of my registered cursors that they are now * invalid. */ protected void invalidateCursors() { Iterator it = _cursors.iterator(); while (it.hasNext()) { WeakReference ref = (WeakReference) it.next(); Cursor cursor = (Cursor) ref.get(); if (cursor != null) { // cursor is null if object has been garbage-collected cursor.invalidate(); ref.clear(); } it.remove(); } } /** * Informs all of my registered cursors that the specified * element was changed. * @see #set(int,java.lang.Object) */ protected void broadcastListableChanged(Listable elt) { Iterator it = _cursors.iterator(); while (it.hasNext()) { WeakReference ref = (WeakReference) it.next(); Cursor cursor = (Cursor) ref.get(); if (cursor == null) { it.remove(); // clean up list } else { cursor.listableChanged(elt); } } } /** * Informs all of my registered cursors that the specified * element was just removed from my list. */ protected void broadcastListableRemoved(Listable elt) { Iterator it = _cursors.iterator(); while (it.hasNext()) { WeakReference ref = (WeakReference) it.next(); Cursor cursor = (Cursor) ref.get(); if (cursor == null) { it.remove(); // clean up list } else { cursor.listableRemoved(elt); } } } /** * Informs all of my registered cursors that the specified * element was just added to my list. */ protected void broadcastListableInserted(Listable elt) { Iterator it = _cursors.iterator(); while (it.hasNext()) { WeakReference ref = (WeakReference) it.next(); Cursor cursor = (Cursor) ref.get(); if (cursor == null) { it.remove(); // clean up list } else { cursor.listableInserted(elt); } } } private void writeObject(ObjectOutputStream out) throws IOException { out.defaultWriteObject(); out.writeInt(_size); Listable cur = _head.next(); while (cur != null) { out.writeObject(cur.value()); cur = cur.next(); } } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); _size = 0; _modCount = 0; _cursors = new ArrayList(); _head = new Listable(null,null,null); int size = in.readInt(); for (int i=0;i<size;i++) { this.add(in.readObject()); } } //--- protected attributes --------------------------------------- /** The number of elements in me. */ protected transient int _size = 0; /** * A sentry node. * <p> * <tt>_head.next()</tt> points to the first element in the list, * <tt>_head.prev()</tt> to the last. Note that it is possible for * <tt>_head.next().prev()</tt> and <tt>_head.prev().next()</tt> to be * non-null, as when I am a sublist for some larger list. * Use <tt>== _head.next()</tt> and <tt>== _head.prev()</tt> to determine * if a given * {@link org.apache.commons.collections.CursorableLinkedList.Listable} * is the first or last element in the list. */ protected transient Listable _head = new Listable(null,null,null); /** Tracks the number of structural modifications to me. */ protected transient int _modCount = 0; /** * A list of the currently {@link CursorableLinkedList.Cursor}s currently * open in this list. */ protected transient List _cursors = new ArrayList(); //--- inner classes ---------------------------------------------- static class Listable implements Serializable { private static final long serialVersionUID = 1L; private Listable _prev = null; private Listable _next = null; private Object _val = null; Listable(Listable prev, Listable next, Object val) { _prev = prev; _next = next; _val = val; } Listable next() { return _next; } Listable prev() { return _prev; } Object value() { return _val; } void setNext(Listable next) { _next = next; } void setPrev(Listable prev) { _prev = prev; } Object setValue(Object val) { Object temp = _val; _val = val; return temp; } } class ListIter implements ListIterator { Listable _cur = null; Listable _lastReturned = null; int _expectedModCount = _modCount; int _nextIndex = 0; ListIter(int index) { if(index == 0) { _cur = new Listable(null,_head.next(),null); _nextIndex = 0; } else if(index == _size) { _cur = new Listable(_head.prev(),null,null); _nextIndex = _size; } else { Listable temp = getListableAt(index); _cur = new Listable(temp.prev(),temp,null); _nextIndex = index; } } public Object previous() { checkForComod(); if(!hasPrevious()) { throw new NoSuchElementException(); } else { Object ret = _cur.prev().value(); _lastReturned = _cur.prev(); _cur.setNext(_cur.prev()); _cur.setPrev(_cur.prev().prev()); _nextIndex--; return ret; } } public boolean hasNext() { checkForComod(); return(null != _cur.next() && _cur.prev() != _head.prev()); } public Object next() { checkForComod(); if(!hasNext()) { throw new NoSuchElementException(); } else { Object ret = _cur.next().value(); _lastReturned = _cur.next(); _cur.setPrev(_cur.next()); _cur.setNext(_cur.next().next()); _nextIndex++; return ret; } } public int previousIndex() { checkForComod(); if(!hasPrevious()) { return -1; } return _nextIndex-1; } public boolean hasPrevious() { checkForComod(); return(null != _cur.prev() && _cur.next() != _head.next()); } public void set(Object o) { checkForComod(); try { _lastReturned.setValue(o); } catch(NullPointerException e) { throw new IllegalStateException(); } } public int nextIndex() { checkForComod(); if(!hasNext()) { return size(); } return _nextIndex; } public void remove() { checkForComod(); if(null == _lastReturned) { throw new IllegalStateException(); } else { _cur.setNext(_lastReturned == _head.prev() ? null : _lastReturned.next()); _cur.setPrev(_lastReturned == _head.next() ? null : _lastReturned.prev()); removeListable(_lastReturned); _lastReturned = null; _nextIndex--; _expectedModCount++; } } public void add(Object o) { checkForComod(); _cur.setPrev(insertListable(_cur.prev(),_cur.next(),o)); _lastReturned = null; _nextIndex++; _expectedModCount++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -