Java N维数组

10

我需要一个n维度的场,其中n基于构造函数的输入。但我甚至不确定这是否可能。是吗?


1
你能澄清一下你想要的是什么吗?从你的问题中,很容易理解出四五个不同的要求... - T.J. Crowder
3个回答

9
快速解决方案:你可以用非泛型的ArrayList,它包含多个ArrayList,这些ArrayList可以一直嵌套下去。然而,这样使用起来可能会很麻烦。
另一种需要更多工作的替代方法是使用底层的平面数组表示来实现自己的类型,在内部计算索引并提供带有可变参数的访问器方法。我不确定它是否完全可行,但值得一试...
粗略的示例(未经测试,没有溢出检查,错误处理等,但希望传达基本思想):
class NDimensionalArray {
  private Object[] array; // internal representation of the N-dimensional array
  private int[] dimensions; // dimensions of the array
  private int[] multipliers; // used to calculate the index in the internal array

  NDimensionalArray(int... dimensions) {
    int arraySize = 1;

    multipliers = new int[dimensions.length];
    for (int idx = dimensions.length - 1; idx >= 0; idx--) {
      multipliers[idx] = arraySize;
      arraySize *= dimensions[idx];
    }
    array = new Object[arraySize];
    this.dimensions = dimensions;
  }
  ...
  public Object get(int... indices) {
    assert indices.length == dimensions.length;
    int internalIndex = 0;

    for (int idx = 0; idx < indices.length; idx++) {
      internalIndex += indices[idx] * multipliers[idx];
    }
    return array[internalIndex];
  }
  ...
}

我同意你的第一次评估,集合是正确的选择。然而,你的解决方案可能比通过这种方式实现的泛型规范混乱得更加清晰(即List<List<List<List<List...<String>>>>)。 - user439793
1
@John,即使使用泛型也无法在运行时组装/更改泛型类型参数。例如,对于3个维度,最外层的列表需要是List<List<List...<String>>>,但对于7个维度,则需要List<List<List<List<List<List<List...<String>>>>>>>。同样,所有元素(即内部列表)将是不同类型的 - 代码中无法以统一的方式处理这种情况。 - Péter Török

4
这是一篇很好的文章,它解释了如何使用反射在运行时创建数组:Java Reflection: Arrays。该文章讲解了如何创建一维数组,但是java.lang.reflect.Array还包含另一个newInstance方法来创建多维数组。例如:
int[] dimensions = { 10, 10, 10 }; // 3-dimensional array, 10 elements per dimension
Object myArray = Array.newInstance(String.class, dimensions); // 3D array of strings

由于维数在运行时未知,因此只能将数组作为 Object 处理,并且必须使用 Array 类的 getset 方法来操作数组的元素。


我不确定使用get/set是否太慢而无法使用。如果您正在处理最后一个维度并且成员是原始类型,则可以将其转换为Object []或原始数组。但是,我无法想象如何使用这样的未知维数数组。即使是简单的迭代也意味着使用未知数量的嵌套循环。我会考虑创建一个一维数组,然后使用Horner方案计算索引,例如i1 + dim1 + (i2 + dim2 * (....)),这可以使用简单的循环完成。 - maaartinus


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接