package agg.util.colim;
import java.util.Enumeration;
/**
* IntArray allows a native array of ints to be accessed.
*/
public class IntArray implements Container {
static final int DEFAULT_SIZE = 10;
static final int THRESHOLD = 2000;
static final int MULTIPLIER = 2;
static final int HASH_SIZE = 16;
int array[];
/**
* Construct myself to refer to an empty array.
*/
public IntArray() {
this( new int[ 0 ] );
}
/**
* Construct myself to refer to an existing IntArray.
* @param array The IntArray to copy.
*/
public IntArray( IntArray array ){
this( array.array );
}
/**
* Construct myself to be a copy of an existing IntBuffer.
* @param buffer The IntBuffer to copy.
*/
public IntArray( IntBuffer buffer ){
this( buffer.get() );
}
/**
* Construct myself to refer to a native Java array.
* @param array The int[] to ape.
*/
public IntArray( int array[] ){
this.array = array;
}
/**
* Return a shallow copy of myself.
*/
public synchronized Object clone(){
return new IntArray( this );
}
/**
* Return a string that describes me.
*/
@SuppressWarnings("rawtypes")
public synchronized String toString(){
StringBuffer buffer = new StringBuffer( "int[]" );
buffer.append( "(" );
boolean first = true;
Enumeration iter = this.begin();
while ( iter.hasMoreElements() ){
if ( first ){
buffer.append( " " );
first = false;
}
else
buffer.append( ", " );
buffer.append( iter.nextElement() );
}
if ( first )
buffer.append( ")" );
else
buffer.append( " )" );
return buffer.toString();
}
/**
* Return true if I'm equal to a specified object.
* @param object The object to compare myself against.
* @return true if I'm equal to the specified object.
*/
public boolean equals( Object object ){
return
object instanceof IntArray && equals( (IntArray)object )
|| object instanceof IntBuffer && equals( (IntBuffer)object );
}
/**
* Return true if I contain the same items in the same order as
* another IntArray.
* @param object The IntArray to compare myself against.
* @return true if I'm equal to the specified object.
*/
public boolean equals( IntArray object ){
return equals( object.array );
}
/**
* Return true if I contain the same items in the same order as
* another IntBuffer.
* @param buffer The IntBuffer to compare myself against.
*/
public boolean equals( IntBuffer buffer ){
return equals( buffer.storage );
}
/**
* Return true if I contain the same items in the same order as
* a native array of ints.
* @param array The array to compare myself against.
*/
public synchronized boolean equals( int array[] ){
synchronized( array ){
if ( this.array.length != array.length )
return false;
int i = 0;
while ( i < array.length ){
if ( this.array[ i ] != array[ i ] )
return false;
++i;
}
}
return true;
}
/**
* Retrieve the underlying primitive array.
*/
public int[] get(){
return array;
}
/**
* Return the number of objects that I contain.
*/
public int size(){
return array.length;
}
/**
* Return the maximum number of objects that I can contain.
*/
public int maxSize(){
return array.length;
}
/**
* Return an Enumeration of my components.
*/
@SuppressWarnings("rawtypes")
public Enumeration elements(){
return new IntIterator( this, 0 );
}
/**
* Return an iterator positioned at my first item.
*/
public synchronized IntIterator begin(){
return new IntIterator( this, 0 );
}
/**
* Return an iterator positioned immediately after my last item.
*/
public synchronized IntIterator end(){
return new IntIterator( this, array.length );
}
/**
* Return the Integer object at the specified index.
* @param index The index.
*/
public Object at( int index ){
return new Integer( intAt( index ) );
}
/**
* Return the int at the specified index.
* @param index The index.
*/
public synchronized int intAt( int index ){
return array[ index ];
}
/**
* Return the index of the first object that matches a particular value, or
* -1 if the object is not found. Uses .equals() to find a match
* @param object The object to find.
* @exception java.lang.ClassCastException if objects are not Boolean
*/
public int indexOf( Object object ){
return indexOf( 0, size() - 1, object );
}
/**
* Return an index positioned at the first object within a specified range that
* matches a particular object, or -1 if the object is not found.
* @param first The index of the first object to consider.
* @param last The index of the last object to consider.
* @param object The object to find.
* @exception java.lang.IndexOutOfBoundsException If either index is invalid.
* @exception java.lang.ClassCastException if objects are not Boolean
*/
public synchronized int indexOf( int first, int last, Object object ){
for ( int i=first; i <= last; i++ )
if ( at( i ).equals( object ) )
return i;
return -1;
}
/**
* Return the number of objects within a specified range of that match a
* particular value. the range is inclusive
* @param first The index of the first object to consider.
* @param last The index of the last object to consider.
* @exception java.lang.IndexOutOfBoundsException If either index is invalid.
*/
public synchronized int count( int first, int last, Object object ){
int count = 0;
for ( int i=first; i <= last; i++ )
if ( at( i ).equals( object ) )
++count;
return count;
}
/**
* Replace all elements that match a particular object with a new value and return
* the number of objects that were replaced.
* @param oldValue The object to be replaced.
* @param newValue The value to substitute.
*/
public int replace( Object oldValue, Object newValue ){
return replace( 0, size() - 1, oldValue, newValue );
}
/**
* Replace all elements within a specified range that match a particular object
* with a new value and return the number of objects that were replaced.
* @param first The index of the first object to be considered.
* @param last The index of the last object to be considered.
* @param oldValue The object to be replaced.
* @param newValue The value to substitute.
* @exception java.lang.IndexOutOfBoundsException If either index is invalid.
*/
public synchronized int replace( int first, int last, Object oldValue, Object newValue ){
int count = 0;
for ( int i=first; i <= last; i++ )
if ( at( i ).equals( oldValue ) ){
put( i, newValue );
++count;
}
return count;
}
/**
* Return true if I contain a particular object using .equals()
* @param object The object in question.
*/
public boolean contains( Object object ){
return indexOf( object ) != -1;
}
/**
* Set the object at a specified index. The object must be a Number
* @param index The index.
* @param object The object to place at the specified index.
* @exception java.lang.ClassCastException if object is not a Number
* @exception java.lang.IndexOutOfBoundsException if index is invalid.
*/
public void put( int index, Object object ){
put( index, ( (Number)object ).intValue() );
}
/**
* Set the value of a specified index.
* @param index The index.
* @param object The int to place at the specified index.
* @exception java.lang.IndexOutOfBoundsException if index is invalid.
*/
public synchronized void put( int index, int object ){
array[ index ] = object;
}
/**
* Return my hash code for support of hashing containers
*/
public synchronized int hashCode(){
return orderedHash( begin(), size() );
}
final static int orderedHash( ForwardIterator iter, int length ) {
int h = 0;
int position = 0;
int skip = 1;
if ( length >= HASH_SIZE ){
skip = length / HASH_SIZE;
// insure that first will always exactly reach last
iter.advance( length % HASH_SIZE );
}
while ( iter.hasMoreElements() ){
if ( iter.get() != null )
h ^= iter.get().hashCode() / ( ( position % HASH_SIZE ) + 1 );
++position;
iter.advance( skip );
}
return h;
}
/**
* Return true if I contain no objects.
*/
public boolean isEmpty(){
return size() == 0;
}
/**
* Return my last element.
*/
public Object back(){
return at( size() - 1 );
}
/**
* Return my first element.
*/
public Object front(){
return at( 0 );
}
/**
* Return the number of objects that match a specified object.
* @param object The object to count.
*/
public int count( Object object ){
return count( 0, size() - 1, object );
}
final protected static void checkIndex( int i, int size ){
if ( i < 0 || i >= size )
throw new IndexOutOfBoundsException(
"Attempt to access index " + i + "; valid range is 0.." + ( size - 1 ));
}
final protected static void checkRange( int lo, int hi, int size ){
checkIndex( lo, size );
checkIndex( hi, size );
}
final static int getNextSize( int cursize ){
// multiply by MULTIPLIER until THRESHOLD reached; increment by THRESHOLD
// from then on
int newSize = cursize > THRESHOLD
? cursize + THRESHOLD
: cursize * MULTIPLIER;
return Math.max( 1, newSize );
}
/**
* Remove all of my objects. By default, this method throws an exception.
* @exception RuntimeException Thrown by default.
*/
public void clear(){
throw new RuntimeException( "cannot execute clear() on a native array" );
}
/**
* Add an object to myself. By default, this method throws an exception.
* @param object The object to add.
* @exception RuntimeException Thrown by default.
*/
public Object add( Object object ){
throw new RuntimeException( "cannot execute add() on a native array" );
}
}