ObjectSpace Homepage

JGL - The Generic Collection Library for Java
Contents Queues and Stacks Algorithms

Array Adapters

Using a Native Array as a Container
Using a JDK Vector as a Container
Resizeable Native Arrays

One of the primary strengths of JGL is the ability to apply its generic algorithms to JGL containers, native Java arrays, and JDK data structures. The way that it does this is to define the algorithms to accept data structures that implement the Container interface and then to supply special adapter classes that allow native Java arrays and JDK data structures to act as if they were a JGL Container. These adapter classes are found in the com.objectspace.jgl.adapters package. Here is a diagram that shows all of the JGL array adapters:

This chapter describes the adapter classes for native Java arrays and JDK containers.


Using a Native Java Array as a Container

There is a separate adapter class for each kind of native Java array. When you enumerate a native Java array of primitives using an adapter class, nextElement() and get() automatically retrieves each primitive as its closest object equivalent as defined in java.lang. Here is a table that shows this information for each type:

Native Array Type Adapter Class Retrieved As
boolean[] BooleanArray
BooleanBuffer
Boolean
byte[] ByteArray
ByteBuffer
Integer
char[] CharArray
CharBuffer
Character
short[] ShortArray
ShortBuffer
Integer
int[] IntArray
IntBuffer
Integer
long[] LongArray
LongBuffer
Long
float[] FloatArray
FloatBuffer
Float
double[] DoubleArray
DoubleBuffer
Double
Object[] ObjectArray N/A

The adapter classes implement all of the methods defined by the Sequence interface. Because the size of a native Java array is fixed, the add(), clear(), pushBack(), popBack(), pushFront(), popFront(), and remove() methods will always throw an InvalidOperationException. The following example uses an IntArray adapter class to conveniently print, sort, and shuffle a native Java array of ints.



Example Adapters1.java
// Copyright(c) 1996,1997 ObjectSpace, Inc.
import com.objectspace.jgl.*;
import com.objectspace.jgl.adapters.*;
import com.objectspace.jgl.algorithms.*;

public class Adapters1
  {
  public static void main( String[] args )
    {
    int ints[] = { 3, -1, 2, -3, 4 };
    IntArray intArray = new IntArray( ints );
    System.out.println( "Unsorted native int array = " + intArray );

    Sorting.sort( intArray );
    System.out.println( "Sorted = " + intArray );

    Shuffling.randomShuffle( intArray );
    System.out.println( "Randomized = " + intArray );

    for ( int i = 0; i < ints.length; i++ )
      System.out.print( ints[ i ] + " " );
    System.out.println();
    }
  }

Output
Unsorted native int array = int[]( 3, -1, 2, -3, 4 )
Sorted = int[]( -3, -1, 2, 3, 4 )
Randomized = int[]( -1, 3, -3, 2, 4 )
-1 3 -3 2 4


Using a JDK Vector as a Container

The VectorArray adapter class allows a JDK Vector to act as if it were a JGL Container. The add(), clear(), pushFront(), pushback(), popFront(), popBack(), and remove() methods work correctly, and are automatically converted into their JDK equivalents. The following example uses a VectorArray to sort and shuffle a JDK Vector.



Example Adapters2.java
// Copyright(c) 1996,1997 ObjectSpace, Inc.
import com.objectspace.jgl.*;
import com.objectspace.jgl.adapters.*;
import com.objectspace.jgl.algorithms.*;
import java.util.Vector;

public class Adapters2
  {
  public static void main( String[] args )
    {
    Vector vector = new Vector();
    vector.addElement( new Integer( 3 ) );
    vector.addElement( new Integer( -1 ) );
    vector.addElement( new Integer( 2 ) );
    vector.addElement( new Integer( -3 ) );
    vector.addElement( new Integer( 4 ) );

    VectorArray vectorArray = new VectorArray( vector );
    System.out.println( "Unsorted JDK Vector = " + vectorArray );

    Sorting.sort( vectorArray );
    System.out.println( "Sorted = " + vectorArray );

    Shuffling.randomShuffle( vectorArray );
    System.out.println( "Randomized = " + vectorArray );

    System.out.println( "JDK vector = " + vector );
    }
  }

Output
Unsorted JDK Vector = [3, -1, 2, -3, 4]
Sorted = [-3, -1, 2, 3, 4]
Randomized = [-3, -1, 2, 4, 3]
JDK vector = [-3, -1, 2, 4, 3]


Resizeable Native Arrays

The XxxArray classes are designed to simply wrap an existing native array; as a result these classes do not support any dynamic sizing behaviors such as insert() or remove(). Many users wanted this sort of resizable array, so with version 3.0 of JGL the XxxBuffer classes were introduced. This new family of adapters works in the same manner as the originals, but with a few important differences. There is not a resizeable equivalent for the ObjectArray class in this package because com.objectspace.jgl.Array serves that purpose. The following example demonstrates these differences in behavior.



Example Adapters3.java
// Copyright(c) 1997 ObjectSpace, Inc.
import com.objectspace.jgl.*;
import com.objectspace.jgl.adapters.*;
import com.objectspace.jgl.algorithms.*;

public class Adapters3
  {
  public static void main( String[] args )
    {
    // start with a native array
    float floats[] = { 3.0f, -1.1f, 2.0f, -3.1f, 4.0f };
    System.out.print( "native = " );
    Printing.println( FloatIterator.begin( floats ), FloatIterator.end( floats ) );
    System.out.println();

    // FloatArray affects the underlying array
    FloatArray floatArray = new FloatArray( floats );
    System.out.println( "Unsorted = " + floatArray );
    Sorting.sort( floatArray );
    System.out.println( "Sorted = " + floatArray );
    Shuffling.randomShuffle( floatArray );
    System.out.println( "Randomized = " + floatArray );
    System.out.print( "native = " );
    Printing.println( FloatIterator.begin( floats ), FloatIterator.end( floats ) );
    System.out.println();

    // FloatBuffer does not affect the underlying array
    FloatBuffer floatBuffer = new FloatBuffer( floats );
    System.out.println( "Unsorted = " + floatBuffer );
    Sorting.sort( floatBuffer );
    System.out.println( "Sorted = " + floatBuffer );
    Shuffling.randomShuffle( floatBuffer );
    System.out.println( "Randomized = " + floatBuffer );
    System.out.print( "native = " );
    Printing.println( FloatIterator.begin( floats ), FloatIterator.end( floats ) );
    System.out.println();

    // Buffers are resizeable
    floatBuffer.insert( 3, 5.6f );
    System.out.println( "Inserted = " + floatBuffer );
    floatBuffer.remove( 1, 3 );
    System.out.println( "Removed = " + floatBuffer );
    System.out.println();

    // and return to a native array
    floats = floatBuffer.get();
    System.out.print( "native = " );
    Printing.println( FloatIterator.begin( floats ), FloatIterator.end( floats ) );
    }
  }

Output
native = ( 3.0, -1.1, 2.0, -3.1, 4.0 )

Unsorted = float[]( 3.0, -1.1, 2.0, -3.1, 4.0 )
Sorted = float[]( -1.1, -3.1, 2.0, 3.0, 4.0 )
Randomized = float[]( 4.0, -3.1, 3.0, 2.0, -1.1 )
native = ( 4.0, -3.1, 3.0, 2.0, -1.1 )

Unsorted = FloatBuffer( 4.0, -3.1, 3.0, 2.0, -1.1 )
Sorted = FloatBuffer( -1.1, -3.1, 2.0, 3.0, 4.0 )
Randomized = FloatBuffer( 4.0, -1.1, 2.0, 3.0, -3.1 )
native = ( 4.0, -3.1, 3.0, 2.0, -1.1 )

Inserted = FloatBuffer( 4.0, -1.1, 2.0, 5.6, 3.0, -3.1 )
Removed = FloatBuffer( 4.0, 3.0, -3.1 )

native = ( 4.0, 3.0, -3.1 )


Contents Queues and Stacks Algorithms