I have this multidimensional array that generalizes vectors and matrices:
com.github.coderodde.util.MultidimensionalArray.java
:
package com.github.coderodde.util;
/**
* This class implements a multidimensional array.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Nov 13, 2022)
* @since 1.6 (Nov 13, 2022)
*/
public final class MultidimensionalArray<E> {
private final int[] dimensions;
private final E[] storage;
public MultidimensionalArray(int dimension1, int... otherDimensions) {
dimensions = new int[1 + otherDimensions.length];
dimensions[0] = checkDimension(dimension1);
for (int i = 0; i < otherDimensions.length; i++) {
dimensions[i + 1] = checkDimension(otherDimensions[i]);
}
storage = (E[]) new Object[multiplyDimensions()];
}
public E get(int... coordinates) {
checkCoordinates(coordinates);
return storage[convertCoordinatesToIndex(coordinates)];
}
public void set(E element, int... coordinates) {
checkCoordinates(coordinates);
storage[convertCoordinatesToIndex(coordinates)] = element;
}
private void checkCoordinates(int... coordinates) {
if (coordinates.length < dimensions.length) {
throw new IllegalArgumentException(
"The number of coordinates is too small: "
+ coordinates.length
+ ". Must be "
+ dimensions.length
+ ".");
}
if (coordinates.length > dimensions.length) {
throw new IllegalArgumentException(
"The number of coordinates is too large: "
+ coordinates.length
+ ". Must be "
+ dimensions.length
+ ".");
}
for (int i = 0; i < dimensions.length; i++) {
checkCoordinate(coordinates[i], dimensions[i]);
}
}
private void checkCoordinate(int index, int limit) {
if (index < 0) {
throw new IndexOutOfBoundsException(
"Coordinate is negative: "
+ index
+ ". Must be at least zero (0).");
}
if (index >= limit) {
throw new IndexOutOfBoundsException(
"Coordinae is too large: "
+ index
+ ". Must be at most "
+ (limit - 1)
+ ".");
}
}
private int convertCoordinatesToIndex(int... coordinates) {
checkCoordinates(coordinates);
int index = 0;
int multiplier = 1;
for (int i = dimensions.length - 1; i >= 0; i--) {
index += multiplier * coordinates[i];
multiplier *= dimensions[i];
}
return index;
}
private int multiplyDimensions() {
int ret = dimensions[0];
for (int i = 1; i < dimensions.length; i++) {
ret *= dimensions[i];
}
return ret;
}
private static int checkDimension(int dimensionCandidate) {
if (dimensionCandidate < 1) {
throw new IllegalArgumentException(
"Dimension too small: "
+ dimensionCandidate
+ ". Must be at least 1.");
}
return dimensionCandidate;
}
}
com.github.coderodde.util.Demo.java
:
package com.github.coderodde.util;
public final class Demo {
public static void main(String[] args) {
MultidimensionalArray<Integer> arr =
new MultidimensionalArray<>(2, 3, 4);
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 4; k++) {
arr.set(100 * i + 10 * j + k, i, j, k);
}
}
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 4; k++) {
System.out.println(arr.get(i, j, k));
}
}
}
}
}
com.github.coderodde.util.MultidimensionalArrayTest.java
:
package com.github.coderodde.util;
import org.junit.Test;
import static org.junit.Assert.*;
public final class MultidimensionalArrayTest {
@Test
public void setAndGet() {
MultidimensionalArray<Integer> arr =
new MultidimensionalArray<>(2, 3, 5);
arr.set(1, 1, 2, 0);
arr.set(2, 0, 0, 4);
assertEquals(Integer.valueOf(1), arr.get(1, 2, 0));
assertEquals(Integer.valueOf(2), arr.get(0, 0, 4));
}
@Test(expected = IllegalArgumentException.class)
public void throwsOnTooManyCoordinates() {
MultidimensionalArray<Integer> arr =
new MultidimensionalArray<>(3, 2, 4, 5);
arr.get(0, 1, 1, 2, 0);
}
@Test(expected = IllegalArgumentException.class)
public void throwsOnTooLittleCoordinates() {
MultidimensionalArray<Integer> arr =
new MultidimensionalArray<>(3, 2, 4, 5);
arr.get(0, 1, 1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void throwsOnTooSmallCoordinate() {
MultidimensionalArray<Integer> arr =
new MultidimensionalArray<>(3, 2, 4, 5);
arr.get(0, 1, 1, -1);
}
@Test(expected = IndexOutOfBoundsException.class)
public void throwsOnTooLargeCoordinate() {
MultidimensionalArray<Integer> arr =
new MultidimensionalArray<>(3, 2, 4, 5);
arr.get(0, 2, 1, 0);
}
}
Critique request
As always, I would like to hear anything that comes to mind.