【问题标题】:Java: A two dimensional array is stored in column-major or row-major order?Java:二维数组以列优先还是行优先顺序存储?
【发布时间】:2011-10-01 15:20:57
【问题描述】:

在Java中,多维数组是以列优先还是行优先存储的?

【问题讨论】:

  • Java 并没有真正的 2d 数组,尽管它的 1d 数组可以保存对其他数组的引用以实现 2d 效果。所以这个问题对 Java 来说真的没有意义。
  • 我删除了关于C、Matlab等的参考,并在正文中重复了这个问题。我希望现在我的问题很清楚了。
  • 投票重新开放。 “很难说出这里要问什么” - 真的吗?这对我来说非常清楚。我们甚至得到了三个很好的答案。
  • 为什么这个问题被关闭了?遇到这样完全有效、有意义的问题,我感到很困惑。

标签: java memory multidimensional-array performance


【解决方案1】:

两者都没有。我们有时可能会认为 Java 中的二维数组实际上是对数组的引用数组。它不是线性存储在内存中的。

Java 语言规范在简介中指出了这一点:

该语言支持数组数组,而不是多维数组。

这有几个含义。

  • 数组的数组可以是jagged -- 成员数组可以有不同的长度。
  • 外部数组的成员是引用,可以为空。
  • 克隆外部数组是浅层的 - 成员数组在原始数组和克隆之间共享。

来自JLS, section 10.2, "Array Variables"

数组类型的单个变量可能包含对不同长度数组的引用,因为数组的长度不是其类型的一部分。

来自JLS, section 10.7, "Array Members"

多维数组的克隆是浅的,也就是说它只创建一个新数组。子数组是共享的。

【讨论】:

  • 你确定吗?我认为这是行主要顺序
  • 类似,因为特定行中的列是连续存储的。但是,行本身并不是连续存储的。 C 中的二维数组是一块内存。了解数据是按行优先还是列优先放置在该块中可能很重要。但在一维数组中,只有一种布局。
【解决方案2】:

在 Java 中,只有一维数组。

二维数组基本上只是一维数组的一维数组。

int[ ][ ] table;

table = new int[3][ ];

table[0] = new int[5];

table[1] = new int[5];

table[2] = new int[5];

【讨论】:

    【解决方案3】:

    Java 没有多维数组。它有数组数组。比如,

    int[][]
    

    ...是int[] 的数组(当然int[]int 的数组)。

    因此,Java 既不是列优先也不是行优先(但请参阅下面关于如何读取 a[2][3] 的注释),因为虽然给定数组的条目存储在连续的内存块中,但从属数组将这些条目指向是对完全独立的、不相关的内存块的对象引用。这也意味着 Java 的数组数组本质上是锯齿状[0] 处的条目可能指的是 3 槽数组,[1] 处的条目可能指的是 4 槽数组,@ 987654328@ 可能根本不指代一个数组(它可能有null),也许[3] 指的是一个6 槽数组。

    一张图片值 1k-24 个单词等等:

    +−−−−−−−−−+ +−−−−>|整数[] | +−−−−−−−−−−−−+ | +−−−−−−−−−+ |整数[][] | | | 0:整数 | +−−−−−−−−−−−−+ | | 1:整数 | | 0: int[] |−−−−−−+ | 2:整数 | | 1: int[] |−−−−−−+ +−−−−−−−−−+ | 2:空| | | 3: int[] |−−+ | +−−−−−−−−−+ +−−−−−−−−−−−−+ | +−−−−>|整数[] | | +−−−−−−−−−+ | | 0:整数 | | | 1:整数 | | | 2:整数 | | | 3:整数 | | +−−−−−−−−−+ | | +−−−−−−−−−+ +−−−−−−−−−−|整数[] | +−−−−−−−−−+ | 0:整数 | | 1:整数 | | 2:整数 | | 3:整数 | | 4:整数 | | 5:整数 | +−−−−−−−−−+

    一旦你知道了,你就知道(比如说)a[2][3] 的意思是“获取a 的索引2 处的条目引用的数组,然后获取该从属数组的索引3 引用的条目。”我认为它与行优先顺序非常相似,但并不完全相同。

    【讨论】:

    • 比我的更完整的答案。 +1。 Java 在内存存储方面没有多维数组——但 JLS 本身将 Java 的数组松散地称为“多维数组”。
    • 感谢您的回答,T.J.克劳德。所以,我想以行优先顺序扫描一维数组的数组更有效。
    • @Zouzias:可能。并缓存对行的引用,因为它是对象引用。例如,在 Java 中,a = x[3][2]; 表示 y = x[3]; a = y[2]; 而在(比如说)C 中,a = x[3][2]; 表示 a = *(x + (3 * 2)); 所以你想这样做一次 y = x[3] 并保留对它的引用(尽管一些 JVM——Sun /例如,Oracle 的 HotSpot 非常擅长为您做这件事)。
    • 对 Java 中的 Jagged 数组的解释非常好,是的,我同意 Java 数组与 C 数组不同,在分配它们时不需要任何顺序。它以递归的方式简单地认为是数组数组的数组等等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多