📄 cursorablelinkedlist.java
字号:
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 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++;
}
protected void checkForComod() {
if(_expectedModCount != _modCount) {
throw new ConcurrentModificationException();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -