Place your code into a file named NdArray.java in the directory Round8/ndarray. Remember to
pull task material from
In this task you should implement a fixed
N-dimensional array as a generic container class
NdArray<E>. The idea is that e.g. an
NdArray objecd created as
new NdArray<String>(2, 5, 4) would represent a 3-dimensional
String array whose dimensions
have sizes 2, 5 and 4. To be more precise, the first dimension size would be 2, the second 5 and
third 4. In similar manner
new NdArray<Double>(3, 3, 3, 3, 3) would create a 5-dimensional
Double array whose all 5 dimensions have size 3.
The word “fixed” used in the beginning means that the parameters given to the constructor fix the number and sizes of the array dimensions; they cannot be changed later.
The generic class
NdArray<E> should have the following public features:
Inherits the abstract class
AbstractCollection<E>from the Java class library.
This requires us to implement the member functions
Inheriting the class will in effect make
NdArraya more or less fully featured Java container container class.
NdArrayobjects could e.g. be processed with streams by using the inherited member function
NdArray(Integer firstDimLen, Integer ...furtherDimLens)that receives one or more dimension sizes.
The parameters list the sizes of dimensions 1…``N``.
firstDimLenis the size of the first dimension and
furtherDimLenslists the sizes of dimensions 2…``N`` (if there is more than one dimension).
The first dimension size is received separately in order to force the constructor to receive at least one parameter.
Therefore the overall number of dimensions
N= number of parameters = 1 + number of
furtherDimLensparameters (size of that array).
Each dimension size must be non-negative (0 is allowed).
If some dimension size is negative, throw a
NegativeArraySizeExceptionexception with a message “
Illegal dimension size dimLen.”, where
dimLenis the first negative dimension size among the parameters.
int size()that returns the overall size of the array (multiplication of its dimension sizes). E.g. a 3-dimensional array with dimension sizes 2, 5 and 4 has size 2 · 5 · 4 = 20.
E get(int... indices)that returns the item at the array location specified by
The number of
indicesmust be equal to the number of dimensions
If the number of parameters is wrong, throw an
IllegalArgumentExceptionexception with a message “
The array has N dimensions but x indices were given.”, where
Nis the number of dimensions and
xis the number of
Each index must be legal, that is, in the interval 0…size of the corresponding dimension - 1.
If any dimension is given an illegal index, throw an``IndexOutOfBoundsException`` exception with a message “
Illegal index i for dimension dim of length dimLen."”, where
iis the first illegal index within
dimLenare the ordinal number and size of the corresponding dimension. The ordinal numbers of the dimensions are 1, …,
E.g. if we have a 3-dimensional array with dimension sizes 2, 5 and 4, the call
get(i, j, k)is legal if and only if 0 ≤
i< 2, 0 ≤
j< 5 and 0 ≤
void set(E item, int... indices)that stores
iteminto the array location specified by
indicesparameters are subject to the same rules as in the
getfunction. E.g. the same exceptions are thrown in case of wrong number of indices or an illegal index.
int getDimensions()that returns an array containing the dimension sizes.
The returned array has size
Nand the value at index
itells the size of dimension (``i``+1).
NdArrayprobably maintains this kind of an array internally in order to know its dimension sizes. But note: do not return this kind of internal array directly! Create and return a new array because otherwise the function caller could corrupt internal data by modifying the array.
Implements the interface
Iterable<E>(because the inherited
Iterater the array items in the same order as a typical way of using
Nnested loops where the outermost loop iterates the first dimension, the loop directly inside it iterates the second dimension, and so on.
Define a suitable iterator class that implements
Iterator<E>(e.g. as a private inner class).
If you follow (and it is a good idea) the advice given below, the iterator can be very simple: it would suffice to maintain only information about the current iterator index in a one-dimensional table.
Implement a member function
Iterator<E> iterator()that creates and returns an object of the above described iterator class.
Advice: one relatively simple approach to implement an
N-dimensional array is to store the
items into a one-dimensional array. The main challenge is then how to compute a mapping from
indices to an index of the internal one-dimensional array. The basic principle is described e.g.
in this article
(follow the “row-major” order described first in the article, as that makes iteration trivial). I
do not recommend you to try to implement a “truly” multidimensional solution; it would make the
task much more complicated.
You may test your implementation by using the test program given in the file
and the example output given in the files
output4.txt. Place these files to the same directory with your code, compile the test program
javac *.java, and run the tests as
java NdArrayTest 1,
java NdArrayTest 2,
java NdArrayTest 3 and
java NdArrayTest 4. The expected outputs of these tests are given in
A+ presents the exercise submission form here.