【问题标题】:Java N-Dimensional ArraysJava N 维数组
【发布时间】:2011-06-13 20:15:30
【问题描述】:

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

【问题讨论】:

  • 你能澄清你想要什么吗?在您的问题中很容易阅读大约四五个不同的要求...

标签: java constructor multidimensional-array


【解决方案1】:

快速解决方案:您可以使用非泛型 ArrayListArrayList 来近似它...尽可能深入。但是,如果使用得很快,这可能会变得很尴尬。

另一种需要更多工作的方法是使用底层平面数组表示来实现您自己的类型,您可以在其中计算内部索引,并提供带有可变参数的访问器方法。我不确定它是否完全可行,但可能值得一试......

粗略示例(未测试,没有溢出检查,错误处理等,但希望传达基本思想):

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>>>)
  • @John,它甚至不适用于泛型,因为您无法在运行时组装/更改泛型类型参数。 IE。对于 3 个维度,最外面的列表需要是 List&lt;List&lt;List...&lt;String&gt;&gt;&gt;,但对于 7 个维度,则需要 List&lt;List&lt;List&lt;List&lt;List&lt;List&lt;List...&lt;String&gt;&gt;&gt;&gt;&gt;&gt;&gt;。同样,所有元素(即内部列表)将具有不同的类型 - 无法以统一的方式在代码中处理。
【解决方案2】:

这是一篇很好的文章,它解释了如何在运行时使用反射来创建数组: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[] 或原始数组。但是,我无法想象如何使用这样一个未知维度的数组。即使是简单的迭代也意味着使用未知数量的嵌套循环。我会考虑创建一个一维数组,并使用像i1 + dim1 + (i2 + dim2 * (....)) 这样的霍纳方案来计算索引,这可以使用一个简单的循环来完成。
【解决方案3】:

【讨论】:

    猜你喜欢
    • 2011-05-10
    • 2011-04-11
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多