AbstractList.java (SubList): Make it a top-level private class.
2000-11-03 Bryce McKinlay <bryce@albatross.co.nz> * java/util/AbstractList.java (SubList): Make it a top-level private class. * java/util/LinkedList.java (remove): Do update modCount and knownMod. (add): Ditto. * Makefile.am (ordinary_java_source_files): Add LinkedList.java. * Makefile.in: Rebuilt. From-SVN: r37218
This commit is contained in:
parent
19944601d6
commit
8d218b6742
5 changed files with 284 additions and 275 deletions
|
@ -309,232 +309,230 @@ public abstract class AbstractList extends AbstractCollection implements List
|
|||
knownMod++;
|
||||
}
|
||||
} // AbstractList.Iterator
|
||||
|
||||
static class SubList extends AbstractList
|
||||
{
|
||||
private AbstractList backingList;
|
||||
private int offset;
|
||||
private int size;
|
||||
|
||||
public SubList(AbstractList backing, int fromIndex, int toIndex)
|
||||
{
|
||||
backingList = backing;
|
||||
// FIXME: The `this' prefixes in this class are a workaround for a
|
||||
// gcj bug. They should be removed later.
|
||||
this.modCount = backingList.modCount;
|
||||
offset = fromIndex;
|
||||
size = toIndex - fromIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the two modCount fields to ensure that there has
|
||||
* not been a concurrent modification. It throws an exception if there
|
||||
* has been, and otherwise returns normally.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception ConcurrentModificationException if there has been a
|
||||
* concurrent modification.
|
||||
*/
|
||||
private void checkMod()
|
||||
{
|
||||
if (this.modCount != backingList.modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks that a value is between 0 and size (inclusive). If
|
||||
* it is not, an exception is thrown.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if the value is out of range.
|
||||
*/
|
||||
private void checkBoundsInclusive(int index)
|
||||
{
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||
size);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks that a value is between 0 (inclusive) and size
|
||||
* (exclusive). If it is not, an exception is thrown.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if the value is out of range.
|
||||
*/
|
||||
private void checkBoundsExclusive(int index)
|
||||
{
|
||||
if (index < 0 || index >= size)
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||
size);
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
checkMod();
|
||||
return size;
|
||||
}
|
||||
|
||||
public Object set(int index, Object o)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
o = backingList.set(index + offset, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
public Object get(int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
return backingList.get(index + offset);
|
||||
}
|
||||
|
||||
public void add(int index, Object o)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
backingList.add(index + offset, o);
|
||||
this.modCount++;
|
||||
size++;
|
||||
}
|
||||
|
||||
public Object remove(int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
Object o = backingList.remove(index + offset);
|
||||
this.modCount++;
|
||||
size--;
|
||||
return o;
|
||||
}
|
||||
|
||||
public void removeRange(int fromIndex, int toIndex)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(fromIndex);
|
||||
checkBoundsInclusive(toIndex);
|
||||
|
||||
// this call will catch the toIndex < fromIndex condition
|
||||
backingList.removeRange(offset + fromIndex, offset + toIndex);
|
||||
this.modCount = backingList.modCount;
|
||||
size -= toIndex - fromIndex;
|
||||
}
|
||||
|
||||
public boolean addAll(int index, Collection c)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
int csize = c.size();
|
||||
boolean result = backingList.addAll(offset + index, c);
|
||||
this.modCount = backingList.modCount;
|
||||
size += csize;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
{
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
public ListIterator listIterator(final int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
|
||||
return new ListIterator()
|
||||
{
|
||||
ListIterator i = backingList.listIterator(index + offset);
|
||||
int position = index;
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
checkMod();
|
||||
return position < size;
|
||||
}
|
||||
|
||||
public boolean hasPrevious()
|
||||
{
|
||||
checkMod();
|
||||
return position > 0;
|
||||
}
|
||||
|
||||
public Object next()
|
||||
{
|
||||
if (position < size)
|
||||
{
|
||||
Object o = i.next();
|
||||
position++;
|
||||
return o;
|
||||
}
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public Object previous()
|
||||
{
|
||||
if (position > 0)
|
||||
{
|
||||
Object o = i.previous();
|
||||
position--;
|
||||
return o;
|
||||
}
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public int nextIndex()
|
||||
{
|
||||
return offset + i.nextIndex();
|
||||
}
|
||||
|
||||
public int previousIndex()
|
||||
{
|
||||
return offset + i.previousIndex();
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
i.remove();
|
||||
// FIXME: Uncomment the following line once the compiler is fixed.
|
||||
//SubList.this.modCount++;
|
||||
size--;
|
||||
position = nextIndex();
|
||||
}
|
||||
|
||||
public void set(Object o)
|
||||
{
|
||||
i.set(o);
|
||||
}
|
||||
|
||||
public void add(Object o)
|
||||
{
|
||||
i.add(o);
|
||||
// FIXME: Uncomment the following line once the compiler is fixed.
|
||||
//SubList.this.modCount++;
|
||||
size++;
|
||||
position++;
|
||||
}
|
||||
|
||||
// Here is the reason why the various modCount fields are mostly
|
||||
// ignored in this wrapper listIterator.
|
||||
// IF the backing listIterator is failfast, then the following holds:
|
||||
// Using any other method on this list will call a corresponding
|
||||
// method on the backing list *after* the backing listIterator
|
||||
// is created, which will in turn cause a ConcurrentModException
|
||||
// when this listIterator comes to use the backing one. So it is
|
||||
// implicitly failfast.
|
||||
// If the backing listIterator is NOT failfast, then the whole of
|
||||
// this list isn't failfast, because the modCount field of the
|
||||
// backing list is not valid. It would still be *possible* to
|
||||
// make the iterator failfast wrt modifications of the sublist
|
||||
// only, but somewhat pointless when the list can be changed under
|
||||
// us.
|
||||
// Either way, no explicit handling of modCount is needed.
|
||||
// However modCount++ must be executed in add and remove, and size
|
||||
// must also be updated in these two methods, since they do not go
|
||||
// through the corresponding methods of the subList.
|
||||
};
|
||||
}
|
||||
} // AbstractList.SubList
|
||||
}
|
||||
|
||||
|
||||
|
||||
class SubList extends AbstractList
|
||||
{
|
||||
private AbstractList backingList;
|
||||
private int offset;
|
||||
private int size;
|
||||
|
||||
public SubList(AbstractList backing, int fromIndex, int toIndex)
|
||||
{
|
||||
backingList = backing;
|
||||
modCount = backingList.modCount;
|
||||
offset = fromIndex;
|
||||
size = toIndex - fromIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks the two modCount fields to ensure that there has
|
||||
* not been a concurrent modification. It throws an exception if there
|
||||
* has been, and otherwise returns normally.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception ConcurrentModificationException if there has been a
|
||||
* concurrent modification.
|
||||
*/
|
||||
private void checkMod()
|
||||
{
|
||||
if (modCount != backingList.modCount)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks that a value is between 0 and size (inclusive). If
|
||||
* it is not, an exception is thrown.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if the value is out of range.
|
||||
*/
|
||||
private void checkBoundsInclusive(int index)
|
||||
{
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||
size);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks that a value is between 0 (inclusive) and size
|
||||
* (exclusive). If it is not, an exception is thrown.
|
||||
* Note that since this method is private, it will be inlined.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if the value is out of range.
|
||||
*/
|
||||
private void checkBoundsExclusive(int index)
|
||||
{
|
||||
if (index < 0 || index >= size)
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||
size);
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
checkMod();
|
||||
return size;
|
||||
}
|
||||
|
||||
public Object set(int index, Object o)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
o = backingList.set(index + offset, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
public Object get(int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
return backingList.get(index + offset);
|
||||
}
|
||||
|
||||
public void add(int index, Object o)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
backingList.add(index + offset, o);
|
||||
this.modCount++;
|
||||
size++;
|
||||
}
|
||||
|
||||
public Object remove(int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(index);
|
||||
Object o = backingList.remove(index + offset);
|
||||
this.modCount++;
|
||||
size--;
|
||||
return o;
|
||||
}
|
||||
|
||||
public void removeRange(int fromIndex, int toIndex)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsExclusive(fromIndex);
|
||||
checkBoundsInclusive(toIndex);
|
||||
|
||||
// this call will catch the toIndex < fromIndex condition
|
||||
backingList.removeRange(offset + fromIndex, offset + toIndex);
|
||||
this.modCount = backingList.modCount;
|
||||
size -= toIndex - fromIndex;
|
||||
}
|
||||
|
||||
public boolean addAll(int index, Collection c)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
int csize = c.size();
|
||||
boolean result = backingList.addAll(offset + index, c);
|
||||
this.modCount = backingList.modCount;
|
||||
size += csize;
|
||||
return result;
|
||||
}
|
||||
|
||||
public Iterator iterator()
|
||||
{
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
public ListIterator listIterator(final int index)
|
||||
{
|
||||
checkMod();
|
||||
checkBoundsInclusive(index);
|
||||
|
||||
return new ListIterator()
|
||||
{
|
||||
ListIterator i = backingList.listIterator(index + offset);
|
||||
int position = index;
|
||||
|
||||
public boolean hasNext()
|
||||
{
|
||||
checkMod();
|
||||
return position < size;
|
||||
}
|
||||
|
||||
public boolean hasPrevious()
|
||||
{
|
||||
checkMod();
|
||||
return position > 0;
|
||||
}
|
||||
|
||||
public Object next()
|
||||
{
|
||||
if (position < size)
|
||||
{
|
||||
Object o = i.next();
|
||||
position++;
|
||||
return o;
|
||||
}
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public Object previous()
|
||||
{
|
||||
if (position > 0)
|
||||
{
|
||||
Object o = i.previous();
|
||||
position--;
|
||||
return o;
|
||||
}
|
||||
else
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
public int nextIndex()
|
||||
{
|
||||
return offset + i.nextIndex();
|
||||
}
|
||||
|
||||
public int previousIndex()
|
||||
{
|
||||
return offset + i.previousIndex();
|
||||
}
|
||||
|
||||
public void remove()
|
||||
{
|
||||
i.remove();
|
||||
modCount++;
|
||||
size--;
|
||||
position = nextIndex();
|
||||
}
|
||||
|
||||
public void set(Object o)
|
||||
{
|
||||
i.set(o);
|
||||
}
|
||||
|
||||
public void add(Object o)
|
||||
{
|
||||
i.add(o);
|
||||
modCount++;
|
||||
size++;
|
||||
position++;
|
||||
}
|
||||
|
||||
// Here is the reason why the various modCount fields are mostly
|
||||
// ignored in this wrapper listIterator.
|
||||
// IF the backing listIterator is failfast, then the following holds:
|
||||
// Using any other method on this list will call a corresponding
|
||||
// method on the backing list *after* the backing listIterator
|
||||
// is created, which will in turn cause a ConcurrentModException
|
||||
// when this listIterator comes to use the backing one. So it is
|
||||
// implicitly failfast.
|
||||
// If the backing listIterator is NOT failfast, then the whole of
|
||||
// this list isn't failfast, because the modCount field of the
|
||||
// backing list is not valid. It would still be *possible* to
|
||||
// make the iterator failfast wrt modifications of the sublist
|
||||
// only, but somewhat pointless when the list can be changed under
|
||||
// us.
|
||||
// Either way, no explicit handling of modCount is needed.
|
||||
// However modCount++ must be executed in add and remove, and size
|
||||
// must also be updated in these two methods, since they do not go
|
||||
// through the corresponding methods of the subList.
|
||||
};
|
||||
}
|
||||
} // SubList
|
||||
|
|
|
@ -322,7 +322,7 @@ public class LinkedList extends AbstractSequentialList
|
|||
prev.next = e;
|
||||
prev = e;
|
||||
}
|
||||
// Fix up the links between the last new entry and the following entry.
|
||||
// Link the new chain of entries into the list.
|
||||
prev.next = after;
|
||||
if (after != null)
|
||||
after.previous = e;
|
||||
|
@ -541,7 +541,7 @@ public class LinkedList extends AbstractSequentialList
|
|||
* position, in a list of given size.
|
||||
*/
|
||||
LinkedListItr(int index)
|
||||
{
|
||||
{
|
||||
if (index == size)
|
||||
{
|
||||
next = null;
|
||||
|
@ -621,8 +621,8 @@ public class LinkedList extends AbstractSequentialList
|
|||
|
||||
next = lastReturned.next;
|
||||
previous = lastReturned.previous;
|
||||
// Because the list is being manipulated directly, there's no need to
|
||||
// touch either modCount or knownMod here.
|
||||
modCount++;
|
||||
knownMod++;
|
||||
removeEntry(lastReturned);
|
||||
|
||||
lastReturned = null;
|
||||
|
@ -631,11 +631,27 @@ public class LinkedList extends AbstractSequentialList
|
|||
public void add(Object o)
|
||||
{
|
||||
checkMod();
|
||||
// Because the list is being manipulated directly, there's no need to
|
||||
// touch either modCount or knownMod here.
|
||||
modCount++;
|
||||
knownMod++;
|
||||
Entry e = new Entry(o);
|
||||
addEntry(position, e);
|
||||
e.previous = previous;
|
||||
e.next = next;
|
||||
|
||||
if (previous != null)
|
||||
previous.next = e;
|
||||
else
|
||||
first = e;
|
||||
|
||||
if (next != null)
|
||||
{
|
||||
next.previous = e;
|
||||
next = next.next;
|
||||
}
|
||||
else
|
||||
last = e;
|
||||
|
||||
previous = e;
|
||||
size++;
|
||||
position++;
|
||||
lastReturned = null;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue