diff --git a/src/java/com/samskivert/util/AbstractIntSet.java b/src/java/com/samskivert/util/AbstractIntSet.java
index b425b098..14993ffa 100644
--- a/src/java/com/samskivert/util/AbstractIntSet.java
+++ b/src/java/com/samskivert/util/AbstractIntSet.java
@@ -21,34 +21,59 @@
package com.samskivert.util;
import java.util.AbstractSet;
+import java.util.Collection;
import java.util.Iterator;
/**
- * A base class for {@link IntSet} implementations.
+ * A base class for {@link IntSet} implementations.
+ *
+ * All you really need to do is implement interable and size,
+ * although for performance reasons you'll probably want to override contains.
+ *
+ * To implement a modifiable IntSet, the programmer must additionally override this class's
+ * add and remove methods, which will otherwise throw an
+ * UnsupportedOperationException.
*/
public abstract class AbstractIntSet extends AbstractSet
implements IntSet
{
- @Override // from AbstractSet
- public Iterator iterator ()
+ /**
+ * {@inheritDoc}
+ *
+ * This implementation iterates over the ints in the collection, checking each one in turn
+ * to see if it's the specified value.
+ */
+ // from IntSet
+ public boolean contains (int value)
{
- return interator();
+ // abstract implementation. You should override.
+ for (Interator it = interator(); it.hasNext(); ) {
+ if (it.nextInt() == value) {
+ return true;
+ }
+ }
+ return false;
}
// from IntSet
- public boolean add (int t)
+ public boolean add (int value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ // from IntSet
+ public boolean remove (int value)
{
throw new UnsupportedOperationException();
}
/**
- * Creates an iterator that provides access to our int values without unboxing.
- */
- public abstract Interator interator ();
-
- /**
- * Converts the contents of this set to an int array.
+ * {@inheritDoc}
+ *
+ *
This implementation returns an array containing all the elements returned by the
+ * interator.
*/
+ // from IntSet
public int[] toIntArray ()
{
int[] vals = new int[size()];
@@ -58,4 +83,130 @@ public abstract class AbstractIntSet extends AbstractSet
}
return vals;
}
+
+ @Override // from AbstractSet
+ public Iterator iterator ()
+ {
+ return interator();
+ }
+
+ @Override // from AbstractSet
+ public boolean contains (Object o)
+ {
+ return (o instanceof Integer) && contains(((Integer)o).intValue());
+ }
+
+ @Override // from AbstractSet
+ public boolean add (Integer i)
+ {
+ if (i == null) {
+ throw new NullPointerException();
+ }
+ return add(i.intValue());
+ }
+
+ @Override // from AbstractSet
+ public boolean remove (Object o)
+ {
+ return (o instanceof Integer) && remove(((Integer)o).intValue());
+ }
+
+ @Override // from AbstractSet
+ public boolean equals (Object o)
+ {
+ if (o == this) {
+ return true;
+ }
+
+ if (o instanceof IntSet) {
+ IntSet that = (IntSet)o;
+ return (this.size() == that.size()) && this.containsAll(that);
+ }
+ return super.equals(o);
+ }
+
+ @Override // from AbstractSet
+ public int hashCode ()
+ {
+ int h = 0;
+ for (Interator it = interator(); it.hasNext(); ) {
+ h += it.nextInt();
+ }
+ return h;
+ }
+
+ @Override // from AbstractSet
+ public String toString ()
+ {
+ StringBuilder sb = new StringBuilder("[");
+ Interator it = interator();
+ if (it.hasNext()) {
+ sb.append(it.nextInt());
+ while (it.hasNext()) {
+ sb.append(", ").append(it.nextInt());
+ }
+ }
+ return sb.append(']').toString();
+ }
+
+ @Override // from AbstractSet
+ public boolean containsAll (Collection> c)
+ {
+ if (c instanceof Interable) {
+ for (Interator it = ((Interable) c).interator(); it.hasNext(); ) {
+ if (!contains(it.nextInt())) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return super.containsAll(c);
+ }
+
+ @Override // from AbstractSet
+ public boolean addAll (Collection extends Integer> c)
+ {
+ if (c instanceof Interable) {
+ boolean modified = false;
+ for (Interator it = ((Interable) c).interator(); it.hasNext(); ) {
+ if (add(it.nextInt())) {
+ modified = true;
+ }
+ }
+ return modified;
+ }
+ return super.addAll(c);
+ }
+
+ @Override // from AbstractSet
+ public boolean removeAll (Collection> c)
+ {
+ if (c instanceof Interable) {
+ boolean modified = false;
+ for (Interator it = ((Interable)c).interator(); it.hasNext(); ) {
+ if (remove(it.nextInt())) {
+ modified = true;
+ }
+ }
+ return modified;
+ }
+ return super.removeAll(c);
+ }
+
+ @Override // from AbstractSet
+ public boolean retainAll (Collection> c)
+ {
+ if (c instanceof IntSet) {
+ IntSet that = (IntSet)c;
+ boolean modified = false;
+ for (Interator it = interator(); it.hasNext(); ) {
+ if (!that.contains(it.nextInt())) {
+ it.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+ return super.retainAll(c);
+ }
}
diff --git a/src/java/com/samskivert/util/AbstractInterator.java b/src/java/com/samskivert/util/AbstractInterator.java
new file mode 100644
index 00000000..6fcde827
--- /dev/null
+++ b/src/java/com/samskivert/util/AbstractInterator.java
@@ -0,0 +1,39 @@
+//
+// $Id$
+// samskivert library - useful routines for java programs
+// Copyright (C) 2001-2009 Michael Bayne
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.samskivert.util;
+
+/**
+ * A building-block for writing an Interator.
+ */
+public abstract class AbstractInterator
+ implements Interator
+{
+ // from super interface Iterator
+ public Integer next ()
+ {
+ return Integer.valueOf(nextInt());
+ }
+
+ // from super interface Iterator
+ public void remove ()
+ {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/java/com/samskivert/util/ArrayIntSet.java b/src/java/com/samskivert/util/ArrayIntSet.java
index a78a545c..5604bfb4 100644
--- a/src/java/com/samskivert/util/ArrayIntSet.java
+++ b/src/java/com/samskivert/util/ArrayIntSet.java
@@ -32,8 +32,8 @@ import java.util.NoSuchElementException;
* Provides an {@link IntSet} implementation using a sorted array of integers to maintain the
* contents of the set.
*/
-public class ArrayIntSet extends AbstractSet
- implements IntSet, Cloneable, Serializable
+public class ArrayIntSet extends AbstractIntSet
+ implements Cloneable, Serializable
{
/**
* Construct an ArrayIntSet with the specified starting values.
@@ -124,6 +124,9 @@ public class ArrayIntSet extends AbstractSet
*/
public int get (int index)
{
+ if (index >= _size) {
+ throw new IndexOutOfBoundsException("" + index + " >= " + _size);
+ }
return _values[index];
}
@@ -152,13 +155,13 @@ public class ArrayIntSet extends AbstractSet
return values;
}
- // from interface IntSet
+ @Override // from interface IntSet
public boolean contains (int value)
{
return (binarySearch(value) >= 0);
}
- // from interface IntSet
+ @Override // from interface IntSet
public boolean add (int value)
{
int index = binarySearch(value);
@@ -190,7 +193,7 @@ public class ArrayIntSet extends AbstractSet
return true;
}
- // from interface IntSet
+ @Override // from interface IntSet
public boolean remove (int value)
{
int index = binarySearch(value);
@@ -216,23 +219,19 @@ public class ArrayIntSet extends AbstractSet
// from interface IntSet
public Interator interator ()
{
- return new Interator() {
+ return new AbstractInterator() {
public boolean hasNext () {
return (_pos < _size);
}
public int nextInt () {
- if (_pos == _size) {
+ if (_pos >= _size) {
throw new NoSuchElementException();
} else {
return _values[_pos++];
}
}
- public Integer next () {
- return Integer.valueOf(nextInt());
- }
-
public void remove () {
if (_pos == 0) {
throw new IllegalStateException();
@@ -248,16 +247,7 @@ public class ArrayIntSet extends AbstractSet
};
}
- // from interface IntSet
- public Integer[] toArray (Integer[] a)
- {
- for (int i = 0; i < _size; i++) {
- a[i] = Integer.valueOf(_values[i]);
- }
- return a;
- }
-
- // from interface IntSet
+ @Override // from interface IntSet
public int[] toIntArray ()
{
int[] values = new int[_size];
@@ -265,72 +255,31 @@ public class ArrayIntSet extends AbstractSet
return values;
}
+ @Override // from AbstractSet
+ public Object[] toArray ()
+ {
+ // TODO: this is wrong. We should be creating an Object[]
+ return toArray(new Integer[_size]);
+ }
+
+ // from AbstractSet
+ public Integer[] toArray (Integer[] a)
+ {
+ // TODO: this is wrong. We need to be able to grow the array if necessary
+ // and null-terminate the values if the array is too large
+ for (int i = 0; i < _size; i++) {
+ a[i] = Integer.valueOf(_values[i]);
+ }
+ return a;
+ }
+
@Override // from AbstractSet
public int size ()
{
return _size;
}
- @Override // from AbstractSet
- public boolean isEmpty ()
- {
- return _size == 0;
- }
-
- @Override // from AbstractSet
- public boolean contains (Object o)
- {
- return contains(((Integer)o).intValue());
- }
-
- @Override // from AbstractSet
- public boolean add (Integer o)
- {
- return add(o.intValue());
- }
-
- @Override // from AbstractSet
- public boolean remove (Object o)
- {
- return remove(((Integer)o).intValue());
- }
-
- @Override // from AbstractSet
- public boolean containsAll (Collection> c)
- {
- if (c instanceof Interable) {
- Interator inter = ((Interable) c).interator();
- while (inter.hasNext()) {
- if (!contains(inter.nextInt())) {
- return false;
- }
- }
- return true;
-
- } else {
- return super.containsAll(c);
- }
- }
-
- @Override // from AbstractSet
- public boolean addAll (Collection extends Integer> c)
- {
- if (c instanceof Interable) {
- Interator inter = ((Interable) c).interator();
- boolean modified = false;
- while (inter.hasNext()) {
- if (add(inter.nextInt())) {
- modified = true;
- }
- }
- return modified;
-
- } else {
- return super.addAll(c);
- }
- }
-
- @Override // from AbstractSet
+ @Override // from AbstractIntSet
public boolean retainAll (Collection> c)
{
if (c instanceof IntSet) {
@@ -350,31 +299,17 @@ public class ArrayIntSet extends AbstractSet
}
}
- _size = _size - removals;
+ _size -= removals;
return (removals > 0);
-
- } else {
- return super.retainAll(c);
}
- }
-
- @Override // from AbstractSet
- public Iterator iterator ()
- {
- return interator();
- }
-
- @Override // from AbstractSet
- public Object[] toArray ()
- {
- return toArray(new Integer[_size]);
+ return super.retainAll(c);
}
@Override // from AbstractSet
public void clear ()
{
- Arrays.fill(_values, 0);
_size = 0;
+ //Arrays.fill(_values, 0); // not necessary
}
@Override // from AbstractSet
@@ -400,11 +335,11 @@ public class ArrayIntSet extends AbstractSet
@Override // from AbstractSet
public int hashCode ()
{
- int hashCode = 0;
- for (int i = 0; i < _size; i++) {
- hashCode ^= _values[i];
+ int h = 0;
+ for (int ii = 0; ii < _size; ii++) {
+ h += _values[ii];
}
- return hashCode;
+ return h;
}
@Override // from AbstractSet
@@ -420,12 +355,6 @@ public class ArrayIntSet extends AbstractSet
}
}
- @Override // from AbstractSet
- public String toString ()
- {
- return StringUtil.toString(iterator());
- }
-
/**
* Performs a binary search on our values array, looking for the specified value. Swiped from
* java.util.Arrays because those wankers didn't provide a means by which to
diff --git a/src/java/com/samskivert/util/Collections.java b/src/java/com/samskivert/util/Collections.java
index a2455a4f..ad600434 100644
--- a/src/java/com/samskivert/util/Collections.java
+++ b/src/java/com/samskivert/util/Collections.java
@@ -378,11 +378,11 @@ public class Collections
}
@Override
- public boolean equals(Object o) {
+ public boolean equals(Object o) {
synchronized(mutex) {return c.equals(o);}
}
@Override
- public int hashCode() {
+ public int hashCode() {
synchronized(mutex) {return c.hashCode();}
}
}
diff --git a/src/java/com/samskivert/util/HashIntMap.java b/src/java/com/samskivert/util/HashIntMap.java
index 4e0d11d7..168b6276 100644
--- a/src/java/com/samskivert/util/HashIntMap.java
+++ b/src/java/com/samskivert/util/HashIntMap.java
@@ -397,13 +397,10 @@ public class HashIntMap extends AbstractMap
if (_keySet == null) {
_keySet = new AbstractIntSet() {
@Override public Interator interator () {
- return new Interator () {
+ return new AbstractInterator () {
public boolean hasNext () {
return i.hasNext();
}
- public Integer next () {
- return i.next().getKey();
- }
public int nextInt () {
return i.next().getIntKey();
}
@@ -418,20 +415,17 @@ public class HashIntMap extends AbstractMap
return HashIntMap.this.size();
}
- @Override public boolean contains (Object t) {
+ @Override public boolean contains (int t) {
return HashIntMap.this.containsKey(t);
}
- public boolean contains (int t) {
- return HashIntMap.this.containsKey(t);
- }
-
- @Override public boolean remove (Object o) {
- return (null != HashIntMap.this.remove(o));
- }
-
- public boolean remove (int value) {
- return (null != HashIntMap.this.remove(value));
+ @Override public boolean remove (int value) {
+ // we need to be careful of null values
+ if (contains(value)) {
+ HashIntMap.this.remove(value);
+ return true;
+ }
+ return false;
}
};
}
diff --git a/src/java/com/samskivert/util/IntIntMap.java b/src/java/com/samskivert/util/IntIntMap.java
index 3e490724..def3b76b 100644
--- a/src/java/com/samskivert/util/IntIntMap.java
+++ b/src/java/com/samskivert/util/IntIntMap.java
@@ -321,21 +321,10 @@ public class IntIntMap
return IntIntMap.this.size();
}
- @Override public boolean contains (Object t) {
- return (t instanceof Integer) ? IntIntMap.this.containsKey((Integer)t) : false;
- }
-
public boolean contains (int t) {
return IntIntMap.this.containsKey(t);
}
- @Override public boolean remove (Object o) {
- if (!(o instanceof Integer)) {
- return false;
- }
- return remove(((Integer)o).intValue());
- }
-
public boolean remove (int value) {
// we have to check for presence in the map separately because we have no "not in
// the set" return value
@@ -561,9 +550,9 @@ public class IntIntMap
private int _modCount;
}
- protected class KeyValueInterator implements Interator
+ protected class KeyValueInterator extends AbstractInterator
{
- public KeyValueInterator (boolean keys, IntEntryIterator eiter) {
+ public KeyValueInterator (boolean keys, IntEntryIterator eiter) {
_keys = keys;
_eiter = eiter;
}
@@ -577,10 +566,6 @@ public class IntIntMap
return _eiter.hasNext();
}
- public Integer next () {
- return Integer.valueOf(nextInt());
- }
-
public void remove () {
_eiter.remove();
}