但这似乎并不是人们所期望的。
为什么?
认为形式
T[]是指“T型数组”,那么正如我们所期待
int[]的意思,我们希望“int类型的数组”
int[][]是指“int类型的类型数组的数组”,因为有于没有少的原因
int[]是的
T比
int。
因此,考虑到一个人可以拥有任何类型的数组,它只是遵循这种方式
[,
]并用于声明和初始化数组(就此而言
{,}和
,),没有某种特殊的规则禁止数组的数组,我们免费获得这种使用。
现在,还要考虑使用锯齿数组可以做的其他事情:
- 我们可以有“锯齿状”的数组,其中不同的内部数组的大小不同。
- 我们可以在外部数组中具有空数组,在该数组中进行数据的适当映射,或者允许延迟构建。
- 我们可以故意在数组中使用别名,例如
lookup[1]
与相同的数组lookup[5]
。(这可以节省一些数据集,例如,可以为少量内存中的1,112,064个代码点的全部映射许多Unipre属性,因为可以为具有匹配模式的范围重复属性的叶数组)。 - 一些堆实现可以比内存中的一个大对象更好地处理许多较小的对象。
在某些情况下,这类多维数组很有用。
现在,任何功能的默认状态都未指定且未实现。有人需要决定指定和实现一项功能,否则该功能将不存在。
因为,如上所述,除非有人决定引入特殊的禁止数组阵列功能,否则多维数组的数组阵列将存在。由于基于上述原因,数组的数组很有用,因此做出一个奇怪的决定。
相反,多维数组的排序并不自然地遵循已定义的多维数组,其中数组的定义秩可以大于1,因此可以与一组索引而不是单个索引一起使用。有人需要:
- 确定用于声明,初始化和使用的规范。
- 记录下来。
- 编写实际的代码来执行此操作。
- 测试代码以执行此操作。
- 处理错误,边缘情况,错误报告(实际上不是错误),由修复错误引起的向后兼容性问题。
用户还必须学习此新功能。
因此,这是值得的。一些值得的事情是:
- 如果没有办法做同样的事情。
- 如果做同一件事的方式很奇怪或不为人所知。
- 人们会在类似的情况下期望它。
- 用户自己不能提供类似的功能。
在这种情况下:
- 但是还有。
- C和C ++程序员以及基于其语法的Java已经知道在数组中使用跨步,因此可以直接应用相同的技术
- Java的语法基于C ,类似地,C 仅直接支持多维数组作为数组数组。(除非是静态分配的,但是在Java中数组是对象的情况下,这不是一个比喻)。
- 可以轻松编写一个类,该类包装数组和步幅大小的详细信息,并允许通过一组索引进行访问。
确实,问题不在于“为什么Java没有真正的多维数组”?但是“为什么要这样?”
当然,您支持多维数组的观点是正确的,并且某些语言确实出于这个原因拥有它们,但是,负担仍然是争论一个特征而不是争论不休。
(我听说C#会做类似的事情,尽管我也听到另一个谣言,说CLR实现太糟糕了,不值得拥有……也许只是谣言……)
像许多谣言一样,这里有一个真理要素,但这不是全部真理。
.NET数组确实可以具有多个等级。这不是比Java更灵活的唯一方法。每个等级还可以具有除零以外的下限。这样,例如,您可以拥有一个从-3到42的数组或一个二维数组,其中一个等级从-2到5到另一个等级从57到100,等等。
C#不能从其内置语法中完全访问所有这些内容(您需要调用
Array.CreateInstance()除零以外的下限),但是它允许您将语法
int[,]用于的二维数组
int,
int[,,]对于三个维数组,依此类推。
现在,处理除零以外的下限所涉及的额外工作增加了性能负担,但是这些情况相对不常见。因此,将具有较低下限0的单列数组视为具有更高性能实现的特殊情况。实际上,它们在内部是另一种结构。
在.NET中,下界为零的多维数组被视为其下界恰好为零的多维数组(即,较慢的情况的一个示例),而不是较快的情况能够处理更大的秩比1。
当然,.NET 对于基于零的多维数组 可能 有一个快速路径案例,但是随后所有Java都没有应用它们的原因 以及
事实已经存在一个特殊情况,并且特殊情况很糟糕,然后将有两种特殊情况,它们会吸收更多。(实际上,尝试将一种类型的值分配给另一种类型的变量可能会有一些问题)。
上面没有任何一件事情清楚地表明Java不可能拥有您所说的那种多维数组。这本来是足够明智的决定,但是做出的决定也是明智的。



