AbstractCollection.java (addAll): Use size() instead of hasNext() in iterator loop.

2000-10-29  Bryce McKinlay  <bryce@albatross.co.nz>

	* java/util/AbstractCollection.java (addAll): Use size() instead of
	hasNext() in iterator loop.
	(clear): Ditto.
	(contains): Ditto. Simplify loop.
	(containsAll): Ditto.
	(remove): Ditto.
	(removeAll): Ditto.
	(retainAll): Ditto.
	(toArray): Ditto.
	(toString): Ditto. Use string concatenation operators, not
	StringBuffer.
	* java/util/AbstractList.java (addAll): Use size() instead of
	hasNext() in iterator loop.
	(equals): Ditto.
	(hashCode): Ditto.
	(indexOf): Ditto. Don't take null check outside of the loop.
	(iterator): Return an AbstractListItr instead of anonymous class.
	(lastIndexOf): Use a for loop bounded by size() instead of
	hasPrevious() in iterator loop.
	(listIterator): Return an AbstractListItr.
	(removeRange): Remove bounds checking code and docs.
	(AbstractListItr): New inner class. Code moved here from
	listIterator().
	(SubList.iterator): Removed. Use default implementation from
	AbstractList instead.
	(SubList.listIterator): As above.
	* java/util/AbstractMap.java (clear): Use a for loop bounded by size()
	instead of hasNext() in iterator loop.
	(containsValue): Ditto.
	(equals): Ditto.
	(get): Ditto.
	(put): Ditto.
	(putAll): Ditto.
	(remove): Ditto.
	(toString): Ditto. Use string concatenation operators, not
	StringBuffer.
	* java/util/AbstractSequentialList.java (addAll): Use a for loop
	bounded by size() instead of hasNext() in iterator loop.
	* java/util/AbstractSet.java (hashCode): Don't catch exception as
	part of normal execution flow. Do an explicit null check instead.
	* java/util/ArrayList.java (_iSize): Rename to `size'.
	(_arData): Rename to `data'.
	(get): Check lower bounds also. Simplify IndexOutOfBoundsException
	message.
	(remove): Ditto.
	(removeRange): Make protected. Don't check bounds.
	(add): Check lower bounds also. Simplify IndexOutOfBoundsException
	message.
	(addAll (Collection)): Use a size-bounded for loop instead of hasNext()
	check.
	(addAll (int, Collection)): Check lower bounds. Simplify exception
	string.
	(clone): Clone the data array too.
	(indexOf): Inline doesEqual().
	(lastIndexOf): Ditto.
	(clear): Don't set array data to null.
	(set): Check lower bounds. Simplify exception string.
	(toArray): Correct comment.
	(trimToSize): Don't update modCount, this is not a structural change.
	Add comment.

	* java/util/BitSet.java: Merged with classpath, new JDK 1.2 methods
	implemented.
	(toString): Declare `bit' as long, not int.
	(data): Made package-private, not private.

From-SVN: r37116
This commit is contained in:
Bryce McKinlay 2000-10-29 05:06:10 +00:00 committed by Bryce McKinlay
parent e2d7960734
commit 3a73757880
8 changed files with 980 additions and 892 deletions

View file

@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@ -44,8 +44,8 @@ package java.util;
* AbstractList is documented, so that subclasses can tell which methods could
* be implemented more efficiently.
*/
public abstract class AbstractList extends AbstractCollection implements List {
public abstract class AbstractList extends AbstractCollection implements List
{
/**
* A count of the number of structural modifications that have been made to
* the list (that is, insertions and removals).
@ -54,238 +54,112 @@ public abstract class AbstractList extends AbstractCollection implements List {
public abstract Object get(int index);
public void add(int index, Object o) {
public void add(int index, Object o)
{
throw new UnsupportedOperationException();
}
public boolean add(Object o) {
public boolean add(Object o)
{
add(size(), o);
return true;
}
public boolean addAll(int index, Collection c) {
Iterator i = c.iterator();
if (i.hasNext()) {
do {
add(index++, i.next());
} while (i.hasNext());
return true;
} else {
return false;
}
public boolean addAll(int index, Collection c)
{
Iterator itr = c.iterator();
int size = c.size();
for (int pos = 0; pos < size; pos++)
{
add(index++, itr.next());
}
return (size > 0);
}
public void clear() {
public void clear()
{
removeRange(0, size());
}
public boolean equals(Object o) {
if (o == this) {
public boolean equals(Object o)
{
if (o == this)
return true;
} else if (!(o instanceof List)) {
if (!(o instanceof List))
return false;
} else {
Iterator i1 = iterator();
Iterator i2 = ((List)o).iterator();
while (i1.hasNext()) {
if (!i2.hasNext()) {
return false;
} else {
Object e = i1.next();
if (e == null ? i2.next() != null : !e.equals(i2.next())) {
return false;
}
}
int size = size();
if (size != ((List) o).size())
return false;
Iterator itr1 = iterator();
Iterator itr2 = ((List) o).iterator();
for (int pos = 0; pos < size; pos++)
{
Object e = itr1.next();
if (e == null ? itr2.next() != null : !e.equals(itr2.next()))
return false;
}
if (i2.hasNext()) {
return false;
} else {
return true;
}
}
return true;
}
public int hashCode() {
public int hashCode()
{
int hashCode = 1;
Iterator i = iterator();
while (i.hasNext()) {
Object obj = i.next();
hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
}
Iterator itr = iterator();
int size = size();
for (int pos = 0; pos < size; pos++)
{
Object obj = itr.next();
hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
}
return hashCode;
}
public int indexOf(Object o) {
int index = 0;
ListIterator i = listIterator();
if (o == null) {
while (i.hasNext()) {
if (i.next() == null) {
return index;
}
index++;
public int indexOf(Object o)
{
ListIterator itr = listIterator(0);
int size = size();
for (int pos = 0; pos < size; pos++)
{
if (o == null ? itr.next() == null : o.equals(itr.next()))
return pos;
}
} else {
while (i.hasNext()) {
if (o.equals(i.next())) {
return index;
}
index++;
}
}
return -1;
}
public Iterator iterator() {
return new Iterator() {
private int knownMod = modCount;
private int position = 0;
boolean removed = true;
private void checkMod() {
if (knownMod != modCount) {
throw new ConcurrentModificationException();
}
}
public boolean hasNext() {
checkMod();
return position < size();
}
public Object next() {
checkMod();
removed = false;
try {
return get(position++);
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
public void remove() {
checkMod();
if (removed) {
throw new IllegalStateException();
}
AbstractList.this.remove(--position);
knownMod = modCount;
removed = true;
}
};
public Iterator iterator()
{
return new AbstractListItr(0);
}
public int lastIndexOf(Object o) {
int index = size();
ListIterator i = listIterator(index);
if (o == null) {
while (i.hasPrevious()) {
index--;
if (i.previous() == null) {
return index;
}
public int lastIndexOf(Object o)
{
int size = size();
ListIterator itr = listIterator(size);
for (int pos = size; pos > 0; pos--)
{
if (o == null ? itr.previous() == null : o.equals(itr.previous()))
return pos - 1;
}
} else {
while (i.hasPrevious()) {
index--;
if (o.equals(i.previous())) {
return index;
}
}
}
return -1;
}
public ListIterator listIterator() {
return listIterator(0);
public ListIterator listIterator()
{
return new AbstractListItr(0);
}
public ListIterator listIterator(final int index) {
if (index < 0 || index > size()) {
public ListIterator listIterator(int index)
{
if (index < 0 || index > size())
throw new IndexOutOfBoundsException();
}
return new ListIterator() {
private int knownMod = modCount;
private int position = index;
private int lastReturned = -1;
private void checkMod() {
if (knownMod != modCount) {
throw new ConcurrentModificationException();
}
}
public boolean hasNext() {
checkMod();
return position < size();
}
public boolean hasPrevious() {
checkMod();
return position > 0;
}
public Object next() {
checkMod();
if (hasNext()) {
lastReturned = position++;
return get(lastReturned);
} else {
throw new NoSuchElementException();
}
}
public Object previous() {
checkMod();
if (hasPrevious()) {
lastReturned = --position;
return get(lastReturned);
} else {
throw new NoSuchElementException();
}
}
public int nextIndex() {
checkMod();
return position;
}
public int previousIndex() {
checkMod();
return position - 1;
}
public void remove() {
checkMod();
if (lastReturned < 0) {
throw new IllegalStateException();
}
AbstractList.this.remove(lastReturned);
knownMod = modCount;
position = lastReturned;
lastReturned = -1;
}
public void set(Object o) {
checkMod();
if (lastReturned < 0) {
throw new IllegalStateException();
}
AbstractList.this.set(lastReturned, o);
}
public void add(Object o) {
checkMod();
AbstractList.this.add(position++, o);
lastReturned = -1;
knownMod = modCount;
}
};
return new AbstractListItr(index);
}
public Object remove(int index) {
public Object remove(int index)
{
throw new UnsupportedOperationException();
}
@ -303,59 +177,145 @@ public abstract class AbstractList extends AbstractCollection implements List {
*
* @param fromIndex the index, inclusive, to remove from.
* @param toIndex the index, exclusive, to remove to.
* @exception UnsupportedOperationException if this list does not support
* the removeRange operation.
* @exception IndexOutOfBoundsException if fromIndex > toIndex || fromIndex <
* 0 || toIndex > size().
*/
protected void removeRange(int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException();
} else if (fromIndex < 0 || toIndex > size()) {
throw new IndexOutOfBoundsException();
} else {
ListIterator i = listIterator(fromIndex);
for (int index = fromIndex; index < toIndex; index++) {
i.next();
i.remove();
protected void removeRange(int fromIndex, int toIndex)
{
ListIterator itr = listIterator(fromIndex);
for (int index = fromIndex; index < toIndex; index++)
{
itr.next();
itr.remove();
}
}
}
public Object set(int index, Object o) {
public Object set(int index, Object o)
{
throw new UnsupportedOperationException();
}
public List subList(final int fromIndex, final int toIndex) {
public List subList(final int fromIndex, final int toIndex)
{
if (fromIndex > toIndex)
throw new IllegalArgumentException();
if (fromIndex < 0 || toIndex > size())
throw new IndexOutOfBoundsException();
return new SubList(this, fromIndex, toIndex);
}
static class SubList extends AbstractList {
class AbstractListItr implements ListIterator
{
private int knownMod = modCount;
private int position;
private int lastReturned = -1;
AbstractListItr(int start_pos)
{
this.position = start_pos;
}
private void checkMod()
{
if (knownMod != modCount)
throw new ConcurrentModificationException();
}
public boolean hasNext()
{
checkMod();
return position < size();
}
public boolean hasPrevious()
{
checkMod();
return position > 0;
}
public Object next()
{
checkMod();
if (position < size())
{
lastReturned = position++;
return get(lastReturned);
}
else
{
throw new NoSuchElementException();
}
}
public Object previous()
{
checkMod();
if (position > 0)
{
lastReturned = --position;
return get(lastReturned);
}
else
{
throw new NoSuchElementException();
}
}
public int nextIndex()
{
checkMod();
return position;
}
public int previousIndex()
{
checkMod();
return position - 1;
}
public void remove()
{
checkMod();
if (lastReturned < 0)
{
throw new IllegalStateException();
}
AbstractList.this.remove(lastReturned);
knownMod = modCount;
position = lastReturned;
lastReturned = -1;
}
public void set(Object o)
{
checkMod();
if (lastReturned < 0)
throw new IllegalStateException();
AbstractList.this.set(lastReturned, o);
}
public void add(Object o)
{
checkMod();
AbstractList.this.add(position++, o);
lastReturned = -1;
knownMod = modCount;
}
} // AbstractList.Iterator
static class SubList extends AbstractList
{
private AbstractList backingList;
private int offset;
private int size;
public SubList(AbstractList backing, int fromIndex, int toIndex) {
public SubList(AbstractList backing, int fromIndex, int toIndex)
{
backingList = backing;
upMod();
offset = fromIndex;
size = toIndex - fromIndex;
}
// Note that within this class two fields called modCount are inherited -
// one from the superclass, and one from the outer class.
// The code uses both these two fields and *no other* to provide fail-fast
// behaviour. For correct operation, the two fields should contain equal
// values. Therefore, if this.modCount != backingList.modCount, there
// has been a concurrent modification. This is all achieved purely by using
// the modCount field, precisely according to the docs of AbstractList.
// See the methods upMod and checkMod.
/**
* This method checks the two modCount fields to ensure that there has
* not been a concurrent modification. It throws an exception if there
@ -365,22 +325,23 @@ public abstract class AbstractList extends AbstractCollection implements List {
* @exception ConcurrentModificationException if there has been a
* concurrent modification.
*/
private void checkMod() {
if (this.modCount != backingList.modCount) {
private void checkMod()
{
if (this.modCount != backingList.modCount)
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() {
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.
@ -388,12 +349,12 @@ public abstract class AbstractList extends AbstractCollection implements List {
*
* @exception IndexOutOfBoundsException if the value is out of range.
*/
private void checkBoundsInclusive(int index) {
if (index < 0 || index > size) {
private void checkBoundsInclusive(int index)
{
if (index < 0 || index > size)
throw new IndexOutOfBoundsException();
}
}
/**
* This method checks that a value is between 0 (inclusive) and size
* (exclusive). If it is not, an exception is thrown.
@ -401,131 +362,45 @@ public abstract class AbstractList extends AbstractCollection implements List {
*
* @exception IndexOutOfBoundsException if the value is out of range.
*/
private void checkBoundsExclusive(int index) {
if (index < 0 || index >= size) {
private void checkBoundsExclusive(int index)
{
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException();
}
}
public int size() {
public int size()
{
checkMod();
return size;
}
public Iterator iterator() {
return listIterator();
}
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();
upMod();
size--;
position = nextIndex();
}
public void set(Object o) {
i.set(o);
}
public void add(Object o) {
i.add(o);
upMod();
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 upMod() must be called 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.
};
}
public Object set(int index, Object o) {
public Object set(int index, Object o)
{
checkMod();
checkBoundsExclusive(index);
o = backingList.set(index + offset, o);
upMod();
return o;
}
public Object get(int index) {
public Object get(int index)
{
checkMod();
checkBoundsExclusive(index);
return backingList.get(index + offset);
}
public void add(int index, Object o) {
public void add(int index, Object o)
{
checkMod();
checkBoundsInclusive(index);
backingList.add(index + offset, o);
upMod();
size++;
}
public Object remove(int index) {
public Object remove(int index)
{
checkMod();
checkBoundsExclusive(index);
Object o = backingList.remove(index + offset);
@ -534,18 +409,20 @@ public abstract class AbstractList extends AbstractCollection implements List {
return o;
}
public void removeRange(int fromIndex, int toIndex) {
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);
upMod();
size -= toIndex - fromIndex;
}
public boolean addAll(int index, Collection c) {
public boolean addAll(int index, Collection c)
{
checkMod();
checkBoundsInclusive(index);
int s = backingList.size();
@ -554,5 +431,5 @@ public abstract class AbstractList extends AbstractCollection implements List {
size += backingList.size() - s;
return result;
}
}
} // AbstractList.SubList
}