modify TreeSet.MyIterator to support both ascending and descending iteration

This also fixes a bug such that the remove() method left the iterator
in an inconsistent state.
This commit is contained in:
Joel Dice
2013-12-04 17:52:27 -07:00
parent bb18637f13
commit 2000c139ea
3 changed files with 89 additions and 6 deletions

View File

@ -57,9 +57,7 @@ public class TreeSet<T> extends AbstractSet<T> implements Collection<T> {
}
public Iterator<T> descendingIterator() {
ArrayList<T> iterable = new ArrayList<T>(this);
Collections.reverse(iterable);
return iterable.iterator();
return new MyIterator<T>(set.last(), true);
}
public String toString() {
@ -141,12 +139,18 @@ public class TreeSet<T> extends AbstractSet<T> implements Collection<T> {
private Cell<T> prevCell;
private Cell<T> prevPrevCell;
private boolean canRemove = false;
private final boolean reversed;
private MyIterator(PersistentSet.Path<Cell<T>> path) {
this(path, false);
}
private MyIterator(PersistentSet.Path<Cell<T>> path, boolean reversed) {
this.path = path;
this.reversed = reversed;
if (path != null) {
cell = path.value();
nextPath = path.successor();
nextPath = nextPath();
}
}
@ -157,6 +161,7 @@ public class TreeSet<T> extends AbstractSet<T> implements Collection<T> {
prevCell = start.prevCell;
prevPrevCell = start.prevPrevCell;
canRemove = start.canRemove;
reversed = start.reversed;
}
public boolean hasNext() {
@ -166,7 +171,7 @@ public class TreeSet<T> extends AbstractSet<T> implements Collection<T> {
public T next() {
if (cell == null) {
path = nextPath;
nextPath = path.successor();
nextPath = nextPath();
cell = path.value();
}
prevPrevCell = prevCell;
@ -176,6 +181,10 @@ public class TreeSet<T> extends AbstractSet<T> implements Collection<T> {
return prevCell.value;
}
private PersistentSet.Path nextPath() {
return reversed ? path.predecessor() : path.successor();
}
public void remove() {
if (! canRemove) throw new IllegalStateException();
@ -190,11 +199,12 @@ public class TreeSet<T> extends AbstractSet<T> implements Collection<T> {
} else {
// cell is alone in the list.
set = (PersistentSet) path.remove();
path = path.successor();
path = nextPath;
if (path != null) {
prevCell = null;
cell = path.value();
path = (PersistentSet.Path) set.find((Cell) cell);
nextPath = nextPath();
}
}