我正在尝试创建一个数组数组等数组...,除了我不知道在运行时需要多少嵌套级别。
根据输入的不同,我可能需要int[]
,int[][]
,int[][][][][][]
或其他任何内容。 (对于上下文,我正在尝试为元胞自动机构建 N维网格,其中N作为参数传递。)
我没有任何代码,因为我不知道如何去做;我怀疑只使用数组是不可能的。任何帮助或替代解决方案都将不胜感激。
答案 0 :(得分:10)
您可以使用Object []执行此操作,将其成员限制为Object []或int []。
例如,这是一个数组,在一个部分中有三个深度,在另一个部分中有两个深度:
Object[] myarray = new Object[] {
new Object[] { new int[] { 1, 2 },
new int[] { 3, 4 }},
new int[] { 5, 6 }
};
创建后,您可能想要访问成员。在您的情况下,您知道前面的深度N,因此您知道期望Object []的深度以及期望int []的深度。
但是,如果您不知道深度,可以使用 reflection 来确定成员是另一个Object []级别还是leaf int []。
if ( myarray[0] instanceof Object[] ) {
System.out.println("This should print true.");
}
修改强>
这是一个草图[到目前为止未经测试,对不起]一个方法,在给定索引数组的情况下访问已知深度数组的成员。 m_root成员可以是Object []或int []。 (您可以进一步放松以支持标量。)
public class Grid {
private int m_depth;
private Object m_root;
...
public int get( int ... indices ) {
assert( indices.length == m_depth );
Object level = m_root;
for ( int i = 0; i + 1 < m_depth; ++i ) {
level = ((Object[]) level)[ indices[i] ];
}
int[] row = (int[]) level;
return row[ indices[m_depth - 1] ];
}
}
答案 1 :(得分:1)
这应该可以使用Object[]
来实现,因为数组是对象:
int[] arr = {1,2,3};
int[] arr2 = {1,2,3};
int[] arr3 = {1,2,3};
int[] arr4 = {1,2,3};
Object[] arr5 = {arr, arr2}; // basically an int[][]
Object[] arr6 = {arr3, arr4}; // basically an int[][]
Object[] arr7 = {arr5, arr6}; // basically an int[][][]
// etc.
请注意,一个数组不必包含相同尺寸的数组:
Object[] arr7 = {arr5, arr};
为防止出现这种情况(并允许更轻松地访问数据),我建议您编写一个包含Object
成员的类(将是您的int[]
或Object[]
)和深度变量和一些很好的功能,可以让您访问所需的内容。
ArrayList
也可以使用:
ArrayList array = new ArrayList();
array.add(new ArrayList());
array.add(new ArrayList());
((ArrayList)array.get(0)).add(new ArrayList());
// etc.
答案 2 :(得分:1)
随着嵌套数组的N增加越来越有利,特别是当你有网格结构时。使用这种方法,N的内存使用率呈指数上升,代码变得复杂。
如果您的网格是稀疏填充的(许多具有相同值的单元格),您可以使用一组Cell对象,其中每个对象都包含坐标向量和单元格的整数值。假设不在集合中的每个单元都有一个默认值,这是您最常用的值。
为了更快地访问,您可以使用例如k-d树(https://en.wikipedia.org/wiki/K-d_tree),但这取决于您的实际用例。
答案 3 :(得分:1)
答案 4 :(得分:0)
多维数组的整个构造只是编译器在大块内存上为你做了一些工作(好吧,因为有人在java中注释这是多个内存块)。处理您遇到的问题的一种方法是在运行时使用嵌套的arraylists。另一种(更高性能)方法是只分配您需要的大小的一维数组并自己进行索引。然后,您可以在传递所有细节的方法中隐藏索引代码,例如数组取消引用。
private int[] doAllocate(int[] dimensions)
{
int totalElements = dimensions[0];
for (int i=1; i< dimensions.length; i++)
{
totalElements *= dimensions[i];
}
int bigOne = new int[totalElements];
return bigOne;
}
private int deReference(int[] dimensions, int[] indicies, int[] bigOne)
{
int index = 0;
// Not sure if this is only valid when the dimensions are all the same.
for (int i=0; i<dimensions.length; i++)
{
index += Math.pow(dimensions[i],i) * indicies[dimensions.length - (i + 1)];
}
return bigOne[index];
}
答案 5 :(得分:0)
您可以使用Java反射,因为数组是对象。
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, ClassNotFoundException {
Class<?> intClass = int.class;
Class<?> oneDimensionalArrayClass = Class.forName("[I");
Object oneDimensionalIntArray1 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray1, 0, 1);
Object oneDimensionalIntArray2 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray2, 0, 2);
Object oneDimensionalIntArray3 = Array.newInstance(intClass, 1);
Array.set(oneDimensionalIntArray3, 0, 3);
Object twoDimensionalIntArray = Array.newInstance(oneDimensionalArrayClass, 3);
Array.set(twoDimensionalIntArray, 0, oneDimensionalIntArray1);
Array.set(twoDimensionalIntArray, 1, oneDimensionalIntArray2);
Array.set(twoDimensionalIntArray, 2, oneDimensionalIntArray1);
System.out.println(Array.get(Array.get(twoDimensionalIntArray, 1), 0));
}
使用静态方法的类Array可以访问项目,同时可以使用前导数“[”指定数组的维度。
答案 6 :(得分:0)
上面写的字段是由编译器检查并创建的。如果您想在运行时期间使用动态数据结构,则可以创建自己的数据结构。搜索Composite Pattern
。一个小片段应该告诉你它是如何工作的:
interface IGrid {
void insert(IGrid subgrid);
void insert(int[] values);
}
class Grid implements IGrid {
private IGrid subgrid;
void insert(IGrid subgrid) {this.subgrid = subgrid;}
void insert(int[] values) {/* Do nothing */}
}
class SubGrid implements IGrid {
private int[] values;
void insert(IGrid subgrid) {/* Do nothing */}
void insert(int[] values) {this.values = values;}
}
您只需为Subgrid
创建int[]
,或为Grid
创建Subgrid
int[][]
。这只是一个基本的解决方案,你必须创建一些代码来处理你的自动机的级别和值。我会这样做的。希望它会有所帮助:)并期待更多的解决方案^^