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:
Bryce McKinlay 2000-11-02 10:08:03 +00:00 committed by Bryce McKinlay
parent 17e2e7f92d
commit 7177dab5c9
5 changed files with 660 additions and 455 deletions

View File

@ -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>
* scripts/encodings.pl: Added `ASCII' alias.

View File

@ -145,15 +145,22 @@ public abstract class AbstractList extends AbstractCollection implements List
return -1;
}
/**
* Return an Iterator over this List. This implementation calls
* listIterator(0).
*
* @return an Iterator over this List
*/
public ListIterator listIterator()
{
return new AbstractListItr(0);
return listIterator(0);
}
public ListIterator listIterator(int index)
{
if (index < 0 || index > size())
throw new IndexOutOfBoundsException();
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
size());
return new AbstractListItr(index);
}
@ -193,10 +200,10 @@ public abstract class AbstractList extends AbstractCollection implements List
throw new UnsupportedOperationException();
}
public List subList(final int fromIndex, final int toIndex)
public List subList(int fromIndex, int toIndex)
{
if (fromIndex > toIndex)
throw new IllegalArgumentException();
throw new IllegalArgumentException(fromIndex + " > " + toIndex);
if (fromIndex < 0 || toIndex > size())
throw new IndexOutOfBoundsException();
@ -208,6 +215,7 @@ public abstract class AbstractList extends AbstractCollection implements List
private int knownMod = modCount;
private int position;
private int lastReturned = -1;
private int size = size();
AbstractListItr(int start_pos)
{
@ -223,7 +231,7 @@ public abstract class AbstractList extends AbstractCollection implements List
public boolean hasNext()
{
checkMod();
return position < size();
return position < size;
}
public boolean hasPrevious()
@ -235,7 +243,7 @@ public abstract class AbstractList extends AbstractCollection implements List
public Object next()
{
checkMod();
if (position < size())
if (position < size)
{
lastReturned = position++;
return get(lastReturned);
@ -280,7 +288,7 @@ public abstract class AbstractList extends AbstractCollection implements List
throw new IllegalStateException();
}
AbstractList.this.remove(lastReturned);
knownMod = modCount;
knownMod++;
position = lastReturned;
lastReturned = -1;
}
@ -298,7 +306,7 @@ public abstract class AbstractList extends AbstractCollection implements List
checkMod();
AbstractList.this.add(position++, o);
lastReturned = -1;
knownMod = modCount;
knownMod++;
}
} // AbstractList.Iterator
@ -311,7 +319,9 @@ public abstract class AbstractList extends AbstractCollection implements List
public SubList(AbstractList backing, int fromIndex, int toIndex)
{
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;
size = toIndex - fromIndex;
}
@ -331,17 +341,6 @@ public abstract class AbstractList extends AbstractCollection implements List
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
* it is not, an exception is thrown.
@ -352,7 +351,8 @@ public abstract class AbstractList extends AbstractCollection implements List
private void checkBoundsInclusive(int index)
{
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)
{
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException();
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
size);
}
public int size()
@ -379,7 +380,6 @@ public abstract class AbstractList extends AbstractCollection implements List
checkMod();
checkBoundsExclusive(index);
o = backingList.set(index + offset, o);
upMod();
return o;
}
@ -395,7 +395,7 @@ public abstract class AbstractList extends AbstractCollection implements List
checkMod();
checkBoundsInclusive(index);
backingList.add(index + offset, o);
upMod();
this.modCount++;
size++;
}
@ -404,7 +404,7 @@ public abstract class AbstractList extends AbstractCollection implements List
checkMod();
checkBoundsExclusive(index);
Object o = backingList.remove(index + offset);
upMod();
this.modCount++;
size--;
return o;
}
@ -417,19 +417,122 @@ public abstract class AbstractList extends AbstractCollection implements List
// this call will catch the toIndex < fromIndex condition
backingList.removeRange(offset + fromIndex, offset + toIndex);
upMod();
this.modCount = backingList.modCount;
size -= toIndex - fromIndex;
}
public boolean addAll(int index, Collection c)
{
checkMod();
checkBoundsInclusive(index);
int s = backingList.size();
int csize = c.size();
boolean result = backingList.addAll(offset + index, c);
upMod();
size += backingList.size() - s;
this.modCount = backingList.modCount;
size += csize;
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
}

View File

@ -64,6 +64,12 @@ public abstract class AbstractSequentialList extends AbstractList
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)
{
boolean modified = false;
@ -81,7 +87,8 @@ public abstract class AbstractSequentialList extends AbstractList
{
ListIterator i = listIterator(index);
if (index < 0 || index > size())
throw new IndexOutOfBoundsException();
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
size());
return i.next();
}
@ -100,7 +107,8 @@ public abstract class AbstractSequentialList extends AbstractList
{
ListIterator i = listIterator(index);
if (index < 0 || index > size())
throw new IndexOutOfBoundsException();
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
size());
Object removed = i.next();
i.remove();
return removed;
@ -110,7 +118,8 @@ public abstract class AbstractSequentialList extends AbstractList
{
ListIterator i = listIterator(index);
if (index < 0 || index > size())
throw new IndexOutOfBoundsException();
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
size());
Object old = i.next();
i.set(o);
return old;

View File

@ -43,7 +43,7 @@ import java.io.ObjectStreamField;
* to or removing from the end of a list, checking the size, &c.
*
* @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.List
*/
@ -187,7 +187,7 @@ public class ArrayList extends AbstractList
if (fromIndex != 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)
{
modCount++;
Iterator itr = c.iterator();
int csize = c.size();
modCount++;
ensureCapacity(size + csize);
for (int pos = 0; pos < csize; pos++)
{
@ -240,13 +240,13 @@ public class ArrayList extends AbstractList
*/
public boolean addAll(int index, Collection c)
{
Iterator itr = c.iterator();
int csize = c.size();
modCount++;
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size:" +
size);
modCount++;
Iterator itr = c.iterator();
int csize = c.size();
ensureCapacity(size + csize);
int end = index + csize;
if (size > 0 && index != size)

File diff suppressed because it is too large Load Diff