📄 cursorablelinkedlist.java
字号:
protected void removeAllNodes() {
if (size() > 0) {
// superclass implementation would break all the iterators
Iterator it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
}
//-----------------------------------------------------------------------
/**
* Registers a cursor to be notified of changes to this list.
*
* @param cursor the cursor to register
*/
protected void registerCursor(Cursor cursor) {
// 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(cursor));
}
/**
* Deregisters a cursor from the list to be notified of changes.
*
* @param cursor the cursor to deregister
*/
protected void unregisterCursor(Cursor cursor) {
for (Iterator it = cursors.iterator(); it.hasNext();) {
WeakReference ref = (WeakReference) it.next();
Cursor cur = (Cursor) ref.get();
if (cur == 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 (cur == cursor) {
ref.clear();
it.remove();
break;
}
}
}
//-----------------------------------------------------------------------
/**
* Informs all of my registered cursors that the specified
* element was changed.
*
* @param node the node that was changed
*/
protected void broadcastNodeChanged(Node node) {
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.nodeChanged(node);
}
}
}
/**
* Informs all of my registered cursors that the specified
* element was just removed from my list.
*
* @param node the node that was changed
*/
protected void broadcastNodeRemoved(Node node) {
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.nodeRemoved(node);
}
}
}
/**
* Informs all of my registered cursors that the specified
* element was just added to my list.
*
* @param node the node that was changed
*/
protected void broadcastNodeInserted(Node node) {
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.nodeInserted(node);
}
}
}
//-----------------------------------------------------------------------
/**
* Serializes the data held in this object to the stream specified.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
doWriteObject(out);
}
/**
* Deserializes the data held in this object to the stream specified.
*/
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
doReadObject(in);
}
//-----------------------------------------------------------------------
/**
* An extended <code>ListIterator</code> that allows concurrent changes to
* the underlying list.
*/
public static class Cursor extends AbstractLinkedList.LinkedListIterator {
/** Is the cursor valid (not closed) */
boolean valid = true;
/** Is the next index valid */
boolean nextIndexValid = true;
/**
* Constructs a new cursor.
*
* @param index the index to start from
*/
protected Cursor(CursorableLinkedList parent, int index) {
super(parent, index);
valid = true;
}
/**
* Adds an object to the list.
* The object added here will be the new 'previous' in the iterator.
*
* @param obj the object to add
*/
public void add(Object obj) {
super.add(obj);
// add on iterator does not return the added element
next = next.next;
}
/**
* Gets the index of the next element to be returned.
*
* @return the next index
*/
public int nextIndex() {
if (nextIndexValid == false) {
if (next == parent.header) {
nextIndex = parent.size();
} else {
int pos = 0;
Node temp = parent.header.next;
while (temp != next) {
pos++;
temp = temp.next;
}
nextIndex = pos;
}
nextIndexValid = true;
}
return nextIndex;
}
/**
* Handle event from the list when a node has changed.
*
* @param node the node that changed
*/
protected void nodeChanged(Node node) {
// do nothing
}
/**
* Handle event from the list when a node has been removed.
*
* @param node the node that was removed
*/
protected void nodeRemoved(Node node) {
if (node == next) {
next = node.next;
} else if (node == current) {
current = null;
nextIndex--;
} else {
nextIndexValid = false;
}
}
/**
* Handle event from the list when a node has been added.
*
* @param node the node that was added
*/
protected void nodeInserted(Node node) {
if (node.previous == current) {
next = node;
} else if (next.previous == node) {
next = node;
} else {
nextIndexValid = false;
}
}
/**
* Override superclass modCount check, and replace it with our valid flag.
*/
protected void checkModCount() {
if (!valid) {
throw new ConcurrentModificationException("Cursor closed");
}
}
/**
* Mark this cursor as no longer being needed. Any resources
* associated with this cursor are immediately released.
* In previous versions of this class, it was mandatory to close
* all cursor objects to avoid memory leaks. It is <i>no longer</i>
* necessary to call this close method; an instance of this class
* can now be treated exactly like a normal iterator.
*/
public void close() {
if (valid) {
((CursorableLinkedList) parent).unregisterCursor(this);
valid = false;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -