2005/5/10

     
 

ACDK Arrays

artefaktur

| References | Casting | Arrays | Import | instanceof | Package | Synchronization | Throwable | finally | Dangerous | Stack | String |

In this chapter, you can see how to use arrays and basic types of Objects.


Content of this chapter:

         Intro
         Limitation
         Arrays of basic types
         Array Conversion
         Range Checking
         Dynamic Capacity
         Arrays to Arrays



 Intro
In Java you can use the following constructs:



/* just a test */
int[]
foo()
{
  int[] iarray = new int[3];
  iarray[0] = 1;
  return iarray; // returns via reference
}

String[]
bar()
{
  String[] sarray = new String[2];
  sarray[0] = new String("Hallo");
  return sarray; // returns via reference
}

If you want to use the same mechanism in ACDK, you can use it in the following syntax:

RintArray
foo()
{
  RintArray iarray = new intArray(3);
  iarray[0] = 1;
  return iarray;
}

RStringArray
bar()
{
  RStringArray sarray = new StringArray(2);
  sarray[0] = new String("Hallo");
  return sarray; // returns via reference
}


The remarkable point is, these arrays are also handled as references.

The standard Arraydefinition is:
[TypeName]Array and [ReferenceTypeName]Array.

 Limitation
Initialization Unfortunately, not all initialization expressions work with ACDK:

  // Java
  Object v = new Object();
  String s = new String("asdf");
  Object[2] oarray = new Object[] { v, s };

  // C++ / acdk
  RObject v = new Object();
  RString s = new String("asdf");

  // no direct translation possible
  // has to initialize each node
  RObjectArray oarray = new ObjectArray(2);
  oarray[0] = v;
  oarray[1] = s;

Casting In Java an array of an Object type can be casted to an array of interfaces, the object type implements:

// Java
Integer[] ia = new Integer[2];
Integer i42 = new Integer(42);
Integer i43 = new Integer(43);
Integer i44 = new Integer(44);
ia[0] = i42;
ia[1] = i43;
Comparable[] ca = ia;
ca[0] == i42;
ca[0] = i44; // modify element at index 0
ia[0] == i44; // will also modified in the original Integer[]

In ACDK there is a limitation of casting Object arrays in this way to and from Super-Classes, but not from an Object class array to an interface array.


// ACDK
RIntegerArray ia = new IntegerArray(2);
RInteger i42 = new Integer(42);
RInteger i43 = new Integer(43);
RInteger i44 = new Integer(44);
ia[0] = i42;
ia[1] = i43;

// next line created implicit an new Array
RComparableArray ca = (RComparableArray)ia; // has to cast!
ca[0] == i42; // true
ca[0] = i44; // modify element at index 0 in ComparableArray
ia[0] != i44; // !! original array will not be modified.

In ACDK arrays logically can only cast by value from/to interface arrays.

Implemantation notes:
Although it would possible to implement the Java way of object arrays, the implementation would be quite slower, because every access to and array slot would involve dynamic casting.
See also:  Casting.

 Arrays of basic types

To enable the same idiom in ACDK, the following templated classes are provided:



template <class T> BasicArray; // the Object holding an array of basic types (int, char, long, float, double, bool)
template <class T> RBasicArray; // A reference to this array
template <class T> ObjectArray; // the Object holding the array of Objects
template <class T> RObjectArray; // A reference to this array

For a more simple use of BasicArray, the following typedefs are defined:

typedef BasicArray<char> charArray;
typedef BasicArray<short> shortArray;
typedef BasicArray<int> intArray;
typedef BasicArray<jlong> longArray;
typedef BasicArray<float> floatArray;
typedef BasicArray<double> doubleArray;
typedef BasicArray<bool> boolArray;
typedef BasicArray<bool> booleanArray;
typedef BasicArray<byte> byteArray;

typedef RBasicArray<char> RcharArray;
typedef RBasicArray<short> RshortArray;
typedef RBasicArray<int> RintArray;
typedef RBasicArray<jlong> RlongArray;
typedef RBasicArray<float> RfloatArray;
typedef RBasicArray<double> RdoubleArray;
typedef RBasicArray<bool> RboolArray;
typedef RBasicArray<bool> RbooleanArray;
typedef RBasicArray<byte> RbyteArray;


To create a dump buffer of storage, you can use the following:


RcharArray charray = new charArray(127);
for (int i = 0; i < charray.length(); i++)
  charray[i] = char(i);

Be carful when using CharArray in the context of c-Strings. The class itself will not terminate the string with an ending '\0'.

 Array Conversion


RcharArray charray = new charArray(127);
RIintArray intarray;
intarray = charray; // internal conversion. The Compiler may warn you


 Range Checking


// Create Array with 10 elements
RcharArray charray = new charArray(10);
try {
  // Try to set element out of bounds
  charray[20] = 3; // throws RIndexOutOfBoundsException
} catch (RIndexOutOfBoundsException ex) {
  System::out->println(ex->messageText());
}

 Dynamic Capacity
Unlike in Java, you can resize the capacity of an Array:

/* ensure that the Array has at least newSize elements */
void ObjectArray::ensureCapacity(int newSize):
/* resize the array to exact given newSize. May cut away elements */
void ObjectArrayImpl<T>::resize(int newSize);
ObjectArray::ensureCapacity() does not increase the length of the array, but ensures that resizing the array will not cause reallocation.

 Arrays to Arrays

Internally a template is used to manage Arrays:
  • BasicArray and RBasicArray for basic types like int, char, etc.
  • ObjectArrayImpl and RObjectArrayImpl for other Object arrays.
    To declare an array to an array of Strings you can use:
  • ObjectArrayImpl and RObjectArrayImpl or use an typedef:
  • typedef ObjectArrayImpl StringArrayArray;

     < prevConstructs(3 / 12) next >