AbstractList.java: Throw messages with IndexOutOfBoundsExceptions.
2000-11-02 Bryce McKinlay <bryce@albatross.co.nz> * java/util/AbstractList.java: Throw messages with IndexOutOfBoundsExceptions. (listIterator()): Call listIterator(0). (size): New field. Initialize to size(). (hasNext): Test position against size, not size(). (remove): Increment knownMod by one instead of resetting it from modCount. (add): Ditto. (SubList.upMod): Removed. (SubList.set): Don't call upMod() or update knownMod. (SubList.add(int,Object)): Increment modCount instead of calling upMod(). (SubList.remove): Ditto. (SubList.addAll): Don't call backingList.size(). Increment size from c.size(). (SubList.iterator): New method. Call listIterator(0). (SubList.listIterator): New method. Restore code to return an anonymous listIterator implementation (with some changes). * java/util/AbstractSequentialList.java: Throw messages with IndexOutOfBoundsExceptions. (addAll): Add a specnote. * java/util/ArrayList.java (removeRange): Get the math right. (addAll): Increment modCount _before_ creating iterator. * java/util/LinkedList.java: Rewritten, mostly. From-SVN: r37203
This commit is contained in:
parent
17e2e7f92d
commit
7177dab5c9
5 changed files with 660 additions and 455 deletions
|
@ -1,3 +1,29 @@
|
||||||
|
2000-11-02 Bryce McKinlay <bryce@albatross.co.nz>
|
||||||
|
|
||||||
|
* java/util/AbstractList.java: Throw messages with
|
||||||
|
IndexOutOfBoundsExceptions.
|
||||||
|
(listIterator()): Call listIterator(0).
|
||||||
|
(size): New field. Initialize to size().
|
||||||
|
(hasNext): Test position against size, not size().
|
||||||
|
(remove): Increment knownMod by one instead of resetting it from
|
||||||
|
modCount.
|
||||||
|
(add): Ditto.
|
||||||
|
(SubList.upMod): Removed.
|
||||||
|
(SubList.set): Don't call upMod() or update knownMod.
|
||||||
|
(SubList.add(int,Object)): Increment modCount instead of caling upMod().
|
||||||
|
(SubList.remove): Ditto.
|
||||||
|
(SubList.addAll): Don't call backingList.size(). Increment size from
|
||||||
|
c.size().
|
||||||
|
(SubList.iterator): New method. Call listIterator(0).
|
||||||
|
(SubList.listIterator): New method. Restore code to return an anonymous
|
||||||
|
listIterator implementation (with some changes).
|
||||||
|
* java/util/AbstractSequentialList.java: Throw messages with
|
||||||
|
IndexOutOfBoundsExceptions.
|
||||||
|
(addAll): Add a specnote.
|
||||||
|
* java/util/ArrayList.java (removeRange): Get the math right.
|
||||||
|
(addAll): Increment modCount _before_ creating iterator.
|
||||||
|
* java/util/LinkedList.java: Rewritten, mostly.
|
||||||
|
|
||||||
2000-11-01 Tom Tromey <tromey@cygnus.com>
|
2000-11-01 Tom Tromey <tromey@cygnus.com>
|
||||||
|
|
||||||
* scripts/encodings.pl: Added `ASCII' alias.
|
* scripts/encodings.pl: Added `ASCII' alias.
|
||||||
|
|
|
@ -145,15 +145,22 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an Iterator over this List. This implementation calls
|
||||||
|
* listIterator(0).
|
||||||
|
*
|
||||||
|
* @return an Iterator over this List
|
||||||
|
*/
|
||||||
public ListIterator listIterator()
|
public ListIterator listIterator()
|
||||||
{
|
{
|
||||||
return new AbstractListItr(0);
|
return listIterator(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListIterator listIterator(int index)
|
public ListIterator listIterator(int index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index > size())
|
if (index < 0 || index > size())
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||||
|
size());
|
||||||
|
|
||||||
return new AbstractListItr(index);
|
return new AbstractListItr(index);
|
||||||
}
|
}
|
||||||
|
@ -193,10 +200,10 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List subList(final int fromIndex, final int toIndex)
|
public List subList(int fromIndex, int toIndex)
|
||||||
{
|
{
|
||||||
if (fromIndex > toIndex)
|
if (fromIndex > toIndex)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException(fromIndex + " > " + toIndex);
|
||||||
if (fromIndex < 0 || toIndex > size())
|
if (fromIndex < 0 || toIndex > size())
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
|
|
||||||
|
@ -208,6 +215,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
private int knownMod = modCount;
|
private int knownMod = modCount;
|
||||||
private int position;
|
private int position;
|
||||||
private int lastReturned = -1;
|
private int lastReturned = -1;
|
||||||
|
private int size = size();
|
||||||
|
|
||||||
AbstractListItr(int start_pos)
|
AbstractListItr(int start_pos)
|
||||||
{
|
{
|
||||||
|
@ -223,7 +231,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
public boolean hasNext()
|
public boolean hasNext()
|
||||||
{
|
{
|
||||||
checkMod();
|
checkMod();
|
||||||
return position < size();
|
return position < size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPrevious()
|
public boolean hasPrevious()
|
||||||
|
@ -235,7 +243,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
public Object next()
|
public Object next()
|
||||||
{
|
{
|
||||||
checkMod();
|
checkMod();
|
||||||
if (position < size())
|
if (position < size)
|
||||||
{
|
{
|
||||||
lastReturned = position++;
|
lastReturned = position++;
|
||||||
return get(lastReturned);
|
return get(lastReturned);
|
||||||
|
@ -280,7 +288,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
AbstractList.this.remove(lastReturned);
|
AbstractList.this.remove(lastReturned);
|
||||||
knownMod = modCount;
|
knownMod++;
|
||||||
position = lastReturned;
|
position = lastReturned;
|
||||||
lastReturned = -1;
|
lastReturned = -1;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +306,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
checkMod();
|
checkMod();
|
||||||
AbstractList.this.add(position++, o);
|
AbstractList.this.add(position++, o);
|
||||||
lastReturned = -1;
|
lastReturned = -1;
|
||||||
knownMod = modCount;
|
knownMod++;
|
||||||
}
|
}
|
||||||
} // AbstractList.Iterator
|
} // AbstractList.Iterator
|
||||||
|
|
||||||
|
@ -311,7 +319,9 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
public SubList(AbstractList backing, int fromIndex, int toIndex)
|
public SubList(AbstractList backing, int fromIndex, int toIndex)
|
||||||
{
|
{
|
||||||
backingList = backing;
|
backingList = backing;
|
||||||
upMod();
|
// 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;
|
offset = fromIndex;
|
||||||
size = toIndex - fromIndex;
|
size = toIndex - fromIndex;
|
||||||
}
|
}
|
||||||
|
@ -331,17 +341,6 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
throw new ConcurrentModificationException();
|
throw new ConcurrentModificationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called after every method that causes a structural
|
|
||||||
* modification to the backing list. It updates the local modCount field
|
|
||||||
* to match that of the backing list.
|
|
||||||
* Note that since this method is private, it will be inlined.
|
|
||||||
*/
|
|
||||||
private void upMod()
|
|
||||||
{
|
|
||||||
this.modCount = backingList.modCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks that a value is between 0 and size (inclusive). If
|
* This method checks that a value is between 0 and size (inclusive). If
|
||||||
* it is not, an exception is thrown.
|
* it is not, an exception is thrown.
|
||||||
|
@ -352,7 +351,8 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
private void checkBoundsInclusive(int index)
|
private void checkBoundsInclusive(int index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index > size)
|
if (index < 0 || index > size)
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||||
|
size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -365,7 +365,8 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
private void checkBoundsExclusive(int index)
|
private void checkBoundsExclusive(int index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= size)
|
if (index < 0 || index >= size)
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||||
|
size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size()
|
public int size()
|
||||||
|
@ -379,7 +380,6 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
checkMod();
|
checkMod();
|
||||||
checkBoundsExclusive(index);
|
checkBoundsExclusive(index);
|
||||||
o = backingList.set(index + offset, o);
|
o = backingList.set(index + offset, o);
|
||||||
upMod();
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,7 +395,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
checkMod();
|
checkMod();
|
||||||
checkBoundsInclusive(index);
|
checkBoundsInclusive(index);
|
||||||
backingList.add(index + offset, o);
|
backingList.add(index + offset, o);
|
||||||
upMod();
|
this.modCount++;
|
||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
checkMod();
|
checkMod();
|
||||||
checkBoundsExclusive(index);
|
checkBoundsExclusive(index);
|
||||||
Object o = backingList.remove(index + offset);
|
Object o = backingList.remove(index + offset);
|
||||||
upMod();
|
this.modCount++;
|
||||||
size--;
|
size--;
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
@ -417,19 +417,122 @@ public abstract class AbstractList extends AbstractCollection implements List
|
||||||
|
|
||||||
// this call will catch the toIndex < fromIndex condition
|
// this call will catch the toIndex < fromIndex condition
|
||||||
backingList.removeRange(offset + fromIndex, offset + toIndex);
|
backingList.removeRange(offset + fromIndex, offset + toIndex);
|
||||||
upMod();
|
this.modCount = backingList.modCount;
|
||||||
size -= toIndex - fromIndex;
|
size -= toIndex - fromIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addAll(int index, Collection c)
|
public boolean addAll(int index, Collection c)
|
||||||
{
|
{
|
||||||
checkMod();
|
checkMod();
|
||||||
checkBoundsInclusive(index);
|
checkBoundsInclusive(index);
|
||||||
int s = backingList.size();
|
int csize = c.size();
|
||||||
boolean result = backingList.addAll(offset + index, c);
|
boolean result = backingList.addAll(offset + index, c);
|
||||||
upMod();
|
this.modCount = backingList.modCount;
|
||||||
size += backingList.size() - s;
|
size += csize;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} // AbstractList.SubList
|
|
||||||
|
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();
|
||||||
|
SubList.this.modCount++;
|
||||||
|
size--;
|
||||||
|
position = nextIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Object o)
|
||||||
|
{
|
||||||
|
i.set(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Object o)
|
||||||
|
{
|
||||||
|
i.add(o);
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,12 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||||
i.add(o);
|
i.add(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @specnote The spec in the JDK1.3 online docs is wrong. The implementation
|
||||||
|
* should not call next() to skip over new elements as they are
|
||||||
|
* added, because iterator.add() should add new elements BEFORE
|
||||||
|
* the cursor.
|
||||||
|
*/
|
||||||
public boolean addAll(int index, Collection c)
|
public boolean addAll(int index, Collection c)
|
||||||
{
|
{
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
|
@ -81,7 +87,8 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||||
{
|
{
|
||||||
ListIterator i = listIterator(index);
|
ListIterator i = listIterator(index);
|
||||||
if (index < 0 || index > size())
|
if (index < 0 || index > size())
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||||
|
size());
|
||||||
return i.next();
|
return i.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +107,8 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||||
{
|
{
|
||||||
ListIterator i = listIterator(index);
|
ListIterator i = listIterator(index);
|
||||||
if (index < 0 || index > size())
|
if (index < 0 || index > size())
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||||
|
size());
|
||||||
Object removed = i.next();
|
Object removed = i.next();
|
||||||
i.remove();
|
i.remove();
|
||||||
return removed;
|
return removed;
|
||||||
|
@ -110,7 +118,8 @@ public abstract class AbstractSequentialList extends AbstractList
|
||||||
{
|
{
|
||||||
ListIterator i = listIterator(index);
|
ListIterator i = listIterator(index);
|
||||||
if (index < 0 || index > size())
|
if (index < 0 || index > size())
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||||
|
size());
|
||||||
Object old = i.next();
|
Object old = i.next();
|
||||||
i.set(o);
|
i.set(o);
|
||||||
return old;
|
return old;
|
||||||
|
|
|
@ -43,7 +43,7 @@ import java.io.ObjectStreamField;
|
||||||
* to or removing from the end of a list, checking the size, &c.
|
* to or removing from the end of a list, checking the size, &c.
|
||||||
*
|
*
|
||||||
* @author Jon A. Zeppieri
|
* @author Jon A. Zeppieri
|
||||||
* @version $Id: ArrayList.java,v 1.6 2000/10/26 10:19:00 bryce Exp $
|
* @version $Id: ArrayList.java,v 1.2 2000/10/29 05:06:10 bryce Exp $
|
||||||
* @see java.util.AbstractList
|
* @see java.util.AbstractList
|
||||||
* @see java.util.List
|
* @see java.util.List
|
||||||
*/
|
*/
|
||||||
|
@ -187,7 +187,7 @@ public class ArrayList extends AbstractList
|
||||||
if (fromIndex != toIndex)
|
if (fromIndex != toIndex)
|
||||||
{
|
{
|
||||||
System.arraycopy(data, toIndex, data, fromIndex, size - toIndex);
|
System.arraycopy(data, toIndex, data, fromIndex, size - toIndex);
|
||||||
size -= (fromIndex - toIndex);
|
size -= (toIndex - fromIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,9 +219,9 @@ public class ArrayList extends AbstractList
|
||||||
*/
|
*/
|
||||||
public boolean addAll(Collection c)
|
public boolean addAll(Collection c)
|
||||||
{
|
{
|
||||||
|
modCount++;
|
||||||
Iterator itr = c.iterator();
|
Iterator itr = c.iterator();
|
||||||
int csize = c.size();
|
int csize = c.size();
|
||||||
modCount++;
|
|
||||||
ensureCapacity(size + csize);
|
ensureCapacity(size + csize);
|
||||||
for (int pos = 0; pos < csize; pos++)
|
for (int pos = 0; pos < csize; pos++)
|
||||||
{
|
{
|
||||||
|
@ -240,13 +240,13 @@ public class ArrayList extends AbstractList
|
||||||
*/
|
*/
|
||||||
public boolean addAll(int index, Collection c)
|
public boolean addAll(int index, Collection c)
|
||||||
{
|
{
|
||||||
Iterator itr = c.iterator();
|
|
||||||
int csize = c.size();
|
|
||||||
|
|
||||||
modCount++;
|
|
||||||
if (index < 0 || index > size)
|
if (index < 0 || index > size)
|
||||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
|
||||||
size);
|
size);
|
||||||
|
modCount++;
|
||||||
|
Iterator itr = c.iterator();
|
||||||
|
int csize = c.size();
|
||||||
|
|
||||||
ensureCapacity(size + csize);
|
ensureCapacity(size + csize);
|
||||||
int end = index + csize;
|
int end = index + csize;
|
||||||
if (size > 0 && index != size)
|
if (size > 0 && index != size)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue