Skip to content
Anton Wilhelm edited this page Jun 14, 2013 · 14 revisions

Welcome to the MDAAJ wiki!

What is MDDAJ?

Multi dimensional Dynamic Array Api for Java. You can create dynamic multidimensional generic arrays at runtime.

Getting Started

The conventional way to create arrays looks like this:

int[] a = new int[10];
double[][] b = new double[10][20];
String[][][][][] c = new String[10][20][5][8][15];
c[0][0][2][1][0] = "xyz";
String s = c[0][0][0][0][0];
for (int i=0; i<b.length; i++) {
  for (int j=0; j<b[i].length; i++) {
    b[i][j] = random.nextDouble();
  }
}

Creating the same arrays with MDDAJ:

MDDA<Integer> a = new MDDA<Integer>(10);
MDDA<Double> b = new MDDA<Double>(10,20);
MDDA<String> c = new MDDA<String>(10,20,5,8,15);
c.set("xyz", 0,0,2,1,0);
String s = c.get(0,0,0,0,0);
for (int i=0; i<b.getSize()[0]; i++) {
  for (int j=0; j<getSize()[1]; i++) {
    b.set(random.nextDouble(), i,j);
  }
}

How it works?

The There exist three implementations for the interface MDDAInterface

  • MDDANested The array elements have an inner array and the inner array have an array inside it..., its nested for each dimension.
  • MDDAGenerated For this type, there will be generated a .class (byte code) at runtime with the specific dimensions.
  • MDDA This class provides a multidimensional access for the user, but the array is internally only one dimensional. This type gives best performance!

The MDDAInterface function overview

// set the generic element at the indices (return type indicated if it was successfull)
boolean set(T value, int... indices)

// get the generic element at the indices
public T get(int... indices) 

// fill the whole array with the generic value
public boolean fill(T value) 

// convert the array into one dimensional array
public T[] flatten()

// print the array
public void print(OutputStream out)

// the raw array object
public Object getArray();

// array with elements, which conatain for each dimension the length of the dimension
public int[] getSize();

The MDDA function overview

// copy constructor for MDDA objects
public MDDA (MDDA<T> toCopy);

// copy constructor for native arrays
// bind indicates if the native array should be call by reference or by value
public MDDA(T[] oneDimArray, boolean bind, int... dimensionSize);

// Checks if the array elements of obj are equal
// obj should be a native java array or a MDDA object
public boolean equalArray(Object obj);

// implements the iterator, can be used for foreach loops
public Iterator<T> iterator();

// pretty print 
public void prettyPrint();
// example for this array: {{'a', 'b', 'c'},{'d', 'e', 'f'},{'g', 'h', 'i'}}
[0]	[0]	a
	[1]	b
	[2]	c
[1]	[0]	d
	[1]	e
	[2]	f
[2]	[0]	g
	[1]	h
	[2]	i
	[2]	9

Raw access with MDDAGenerated

MDDAGenerated creates any real array at runtime. You can use the raw object and cast it to an array and using the conventional java access for arrays:

MDDAGenerated<Double> a = MDDAGenerated.createInstance(Double.class, 3,3);
Double[][] raw = (Double[][]) a.getArray();
raw[0][0] = 1.0;
raw[1][1] = 2.0;
raw[2][2] = 3.0;

Access with one dimensional index

MDDA holds every array as one dimensional array. You can also use the index for the internal array. Append for the getter and setter 1D for one dimensional index access.

//return the element with the index for the one dimensional array
public T get1D(int index);

// Sets the element with the index for the one dimensional array
public boolean set1D(T value, int index);

// Calculates the pseudo multidimensonal indices from the one dimensional index
public int[] getMultiDimIndices(int oneDimIndex);

// Calculates the internally one dimensional index
public int calcOneDim(int...indices)


// internally indices structure and multi dimensional access
MDDA<Character> a = 
  new MDDA<Character>(new Character[] {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}, false, 3,3);
// indices with same structure:
// internally indices: {0, 1, 2, 3, 4, 5, 6, 7, 8}
// multi dimensional indices: {(0,0), (0,1), (0,2)}, {(1,0) ,(1,1) ,(1,1)}, {(2,0), (2,1), (2,2)}
// access the index of element 'd' with two different functions:
a.getMultiDimIndices(3); // --> (1,0)
a.calcOneDim(1,0); // --> 3


// convert one dimensional array into multi dimensions
Integer[] d = new Integer[] {1,2,3,4,5,6,7,8,9};
MDDA<Integer> m = new MDDA<Integer>(d, false, 3,3);
// creates an 3x3 array like this:
// new Integer[] {{1,2,3},{4,5,6},{7,8,9}};


// loop over the whole internally array, getter/setter for the one dimensional index 
// a.getArray().length --> length of internally array
for (int i=0; i<a.getArray().length; i++) {
  a.set1D(r.nextDouble(), i);
  lastValue = a.get1D(i);
}

// make sum of all elements with foreach loop
Double sum = 0.0;
// MDDA implements the Iterable, you can use the foreach construct
for (Double elem : a) {
  sum += elem;
}

NeighborInterface

The MDDA implements this interface and provides the neighbors indices of an element for a grid topology. For example in a 2d space your array have the dimension 3x3, MDDA<Integer> a = new MDDA<Integer>(3,3); The numbers are the internal one dimensional indicies:

0 - 1 - 2
|   |   |
3 - 4 - 5
|   |   |
6 - 7 - 8

// internally one dim index <==> multi dim index
a.get1D(0) <= equivalent => a.get(0,0);
a.get1D(1) <= equivalent => a.get(0,1);
a.get1D(2) <= equivalent => a.get(0,2);
a.get1D(3) <= equivalent => a.get(1,0);
a.get1D(4) <= equivalent => a.get(1,1);

The neighbors indices will always used the internally one dim index

int distance = 1; // reachable within one steps from the origin
Set<Integer> getNeighbors = a.getNeighborForAllDims(distance, 1,1)
// getNeighbors = {1,3,5,7}
Set<Integer> getNeighbors2 = a.getNeighborForAllDims(distance+1, 1,1)
// getNeighbors2 = {1,3,5,7,0,2,6,8}

You can also call a.getNeighborForDim(distance, 1, 1,1) for only the 2nd dimension, the result will be {3,5} or a.getNeighborForDim(distance, 0, 1,1) for only the 1st dimension and the result {1,7}