我想在Java中以合适的数据结构表示类似矩阵的数据。这个矩阵的维数取决于用户输入。一种方法可能是使用一个"神奇的"最大常数,并使用一个简单的多维数组。但是对数据的操作很大程度上依赖于维数,我希望避免使用固定数组,因为我总是需要跟踪已使用的维数和最大维数。当然,更动态的方法是定义像
这样的东西private ArrayList<ArrayList<ArrayList<Point>>> arr3d = new ArrayList<ArrayList<ArrayList<Element>>>();
我认为这是不可接受的丑陋。最好是定义一个自定义的数据结构,比如一个一维的ArrayList(或Vector),然后以某种方式包装它,比如映射一个指定为[i,j,k]的访问到那个列表的某个元素。是否可以覆盖操作符[]?如何有效地做到这一点?是否有一些现有的库或代码我可以依靠?
PS:我认为这可能是一个常见的问题,但尽管我尽了最大的努力,我没有发现一个存在的问题。
为什么不创建自己的类来包装它呢?它可以在内部包含你的3d列表,但你只公开"用户友好"的方法来访问和设置元素。
不,在Java中不可能重载[]
一个快速的帮助:
public class Cube<T> {
private final List<List<List<T>>> elements = new ArrayList<List<List<T>>>();
public T get(final int x, final int y, final int z) {
if (elements.size() > x) {
final List<List<T>> rowx = elements.get(x);
if (rowx.size() > y) {
final List<T> rowy = rowx.get(y);
if (rowy.size() > z) {
return rowy.get(z);
}
}
}
return null;
}
}
如果你不担心可读性,你甚至可以在一行中完成:
public T get(final int x, final int y, final int z) {
return (elements.size() > x && elements.get(x).size() > y && elements.get(x).get(y).size() > z ? elements.get(x).get(y).get(z) : null);
}
你需要put方法,它在需要时创建行(作为ArrayList)。
从你的问题中并不能立即弄清楚你所说的矩阵的最大维数是什么意思。它总是三维的,还是基于用户输入的n维的?
假设它是三维的,它是规则的吗?是否每个矩阵[i,j], [i,k]和[j,k]都与其他矩阵相同?
如果是这样,您可以将结构建模为单个平面列表,具有两个变量-一个表示矩阵中单个级别的行长度,另一个表示3d结构中网格的长度。整数除法会给出结构中的三维位置:
给定idx n,行长k和基大小k:
n/K
给出该级别,(n%K)/k
给出该级别中的行。如果我没弄错的话,((n%K))%k
应该给你行内的索引。
将其包装在一个类中,该类包含该逻辑,您可以从外部将其视为3d结构
ArrayList<Point[]>
呢?您甚至可以考虑实现AbstractList
来创建自己的列表(即使您在内部使用ArrayList
)并包装Point
数组创建…