📄 contentlist.java
字号:
if (filter.matches(obj)) {
int adjusted = getAdjustedIndex(index);
old = ContentList.this.get(adjusted);
if (!filter.matches(old)) {
throw new IllegalAddException("Filter won't allow the " +
(old.getClass()).getName() +
" '" + old + "' (index " + index +
") to be removed");
}
old = ContentList.this.set(adjusted, obj);
expected += 2;
}
else {
throw new IllegalAddException("Filter won't allow index " +
index + " to be set to " +
(obj.getClass()).getName());
}
return old;
}
/**
* Return the number of items in this list
*
* @return The number of items in this list.
*/
public int size() {
// Implementation Note: Directly after size() is called, expected
// is sync'd with ContentList.modCount and count provides
// the true size of this view. Before the first call to
// size() or if the backing list is modified outside this
// FilterList, both might contain bogus values and should
// not be used without first calling size();
if (expected == ContentList.this.getModCount()) {
return count;
}
count = 0;
for (int i = 0; i < ContentList.this.size(); i++) {
Object obj = ContentList.this.elementData[i];
if (filter.matches(obj)) {
count++;
}
}
expected = ContentList.this.getModCount();
return count;
}
/**
* Return the adjusted index
*
* @param index Index of in this view.
* @return True index in backing list
*/
final private int getAdjustedIndex(int index) {
int adjusted = 0;
for (int i = 0; i < ContentList.this.size; i++) {
Object obj = ContentList.this.elementData[i];
if (filter.matches(obj)) {
if (index == adjusted) {
return i;
}
adjusted++;
}
}
if (index == adjusted) {
return ContentList.this.size;
}
return ContentList.this.size + 1;
}
}
/* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */
/* * * * * * * * * * * * * FilterListIterator * * * * * * * * * * * */
class FilterListIterator implements ListIterator {
/** The Filter that applies */
Filter filter;
/** Whether this iterator is in forward or reverse. */
private boolean forward = false;
/** Whether a call to remove() is valid */
private boolean canremove = false;
/** Whether a call to set() is valid */
private boolean canset = false;
/** Index in backing list of next object */
private int cursor = -1;
/** the backing index to use if we actually DO move */
private int tmpcursor = -1;
/** Index in ListIterator */
private int index = -1;
/** Expected modCount in our backing list */
private int expected = -1;
/** Number of elements matching the filter. */
private int fsize = 0;
/**
* Default constructor
*/
FilterListIterator(Filter filter, int start) {
this.filter = filter;
expected = ContentList.this.getModCount();
// always start list iterators in backward mode ....
// it makes sense... really.
forward = false;
if (start < 0) {
throw new IndexOutOfBoundsException("Index: " + start);
}
// the number of matching elements....
fsize = 0;
// go through the list, count the matching elements...
for (int i = 0; i < ContentList.this.size(); i++) {
if (filter.matches(ContentList.this.get(i))) {
if (start == fsize) {
// set the back-end cursor to the matching element....
cursor = i;
// set the front-end cursor too.
index = fsize;
}
fsize++;
}
}
if (start > fsize) {
throw new IndexOutOfBoundsException("Index: " + start + " Size: " + fsize);
}
if (cursor == -1) {
// implies that start == fsize (i.e. after the last element
// put the insertion point at the end of the Underlying
// content list ....
// i.e. an add() at this point may potentially end up with
// filtered content between previous() and next()
// the alternative is to put the cursor on the Content after
// the last Content that the filter passed
// The implications are ambiguous.
cursor = ContentList.this.size();
index = fsize;
}
}
/**
* Returns <code>true</code> if this list iterator has a next element.
*/
public boolean hasNext() {
return nextIndex() < fsize;
}
/**
* Returns the next element in the list.
*/
public Object next() {
if (!hasNext())
throw new NoSuchElementException("next() is beyond the end of the Iterator");
index = nextIndex();
cursor = tmpcursor;
forward = true;
canremove = true;
canset = true;
return ContentList.this.get(cursor);
}
/**
* Returns <code>true</code> if this list iterator has more elements
* when traversing the list in the reverse direction.
*/
public boolean hasPrevious() {
return previousIndex() >= 0;
}
/**
* Returns the previous element in the list.
*/
public Object previous() {
if (!hasPrevious())
throw new NoSuchElementException("previous() is before the start of the Iterator");
index = previousIndex();
cursor = tmpcursor;
forward = false;
canremove = true;
canset = true;
return ContentList.this.get(cursor);
}
/**
* Returns the index of the element that would be returned by a
* subsequent call to <code>next</code>.
*/
public int nextIndex() {
checkConcurrentModification();
if (forward) {
// Starting with next possibility ....
for (int i = cursor + 1; i < ContentList.this.size(); i++) {
if (filter.matches(ContentList.this.get(i))) {
tmpcursor = i;
return index + 1;
}
}
// Never found another match.... put the insertion point at
// the end of the list....
tmpcursor = ContentList.this.size();
return index + 1;
}
// We've been going back... so nextIndex() returns the same
// element.
tmpcursor = cursor;
return index;
}
/**
* Returns the index of the element that would be returned by a
* subsequent call to <code>previous</code>. (Returns -1 if the
* list iterator is at the beginning of the list.)
*/
public int previousIndex() {
checkConcurrentModification();
if (!forward) {
// starting with next possibility ....
for (int i = cursor - 1; i >= 0; i--) {
if (filter.matches(ContentList.this.get(i))) {
tmpcursor = i;
return index - 1;
}
}
// Never found another match.... put the insertion point at
// the start of the list....
tmpcursor = -1;
return index - 1;
}
// We've been going forwards... so previousIndex() returns same
// element.
tmpcursor = cursor;
return index;
}
/**
* Inserts the specified element into the list.
*/
public void add(Object obj) {
// Call to nextIndex() will check concurrent.
nextIndex();
// tmpcursor is the backing cursor of the next element
// Remember that List.add(index,obj) is really an insert....
ContentList.this.add(tmpcursor, obj);
forward = true;
expected = ContentList.this.getModCount();
canremove = canset = false;
index = nextIndex();
cursor = tmpcursor;
fsize++;
}
/**
* Removes from the list the last element that was returned by
* the last call to <code>next</code> or <code>previous</code>.
*/
public void remove() {
if (!canremove)
throw new IllegalStateException("Can not remove an "
+ "element unless either next() or previous() has been called "
+ "since the last remove()");
nextIndex(); // to get out cursor ...
ContentList.this.remove(cursor);
cursor = tmpcursor - 1;
expected = ContentList.this.getModCount();
forward = false;
canremove = false;
canset = false;
fsize--;
}
/**
* Replaces the last element returned by <code>next</code> or
* <code>previous</code> with the specified element.
*/
public void set(Object obj) {
if (!canset)
throw new IllegalStateException("Can not set an element "
+ "unless either next() or previous() has been called since the "
+ "last remove() or set()");
checkConcurrentModification();
if (!filter.matches(obj)) {
throw new IllegalAddException("Filter won't allow index " + index + " to be set to "
+ (obj.getClass()).getName());
}
ContentList.this.set(cursor, obj);
expected = ContentList.this.getModCount();
}
/**
* Check if are backing list is being modified by someone else.
*/
private void checkConcurrentModification() {
if (expected != ContentList.this.getModCount()) {
throw new ConcurrentModificationException();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -