【问题标题】:How is a two-dimensional array represented in memory in java?java 内存中的二维数组如何表示?
【发布时间】:2015-02-12 10:49:58
【问题描述】:

我正在尝试使用键、值对实现数据结构,并且正在研究数组实现。

实现此目的的一种方法是为键和值声明单独的一维数组。

  private int[] keys = new int[N];
private int[] values = new int[N];

但是通过如下声明二维数组并且不影响数据局部性,是否可以实现同样的效果?

private int[][] keysAndValues = new int[2][N];

Java 以行优先顺序实现多维数组在这里似乎很重要?以这种方式声明数组是否有任何性能优势,或者这是否会降低代码的可读性?

【问题讨论】:

  • int keysAndValues[2][N] 是 C 语法,而不是 Java。 Java 数组类型不包括数组边界。此外,Java 在声明时不会为数组分配存储空间;你需要一个显式的初始化器。
  • Java 实际上没有多维数组。相反,您拥有对其他数组的引用数组。每个数组都是一维的。

标签: java arrays multidimensional-array


【解决方案1】:

Java 中的二维数组实际上是一个对象引用数组,每个引用指向一个一维数组。 2D 数组和每个 1D 数组都是独立的堆对象,并且可以(理论上)位于堆中的任何位置。

(有关原因的讨论,请参阅:Why doesn't Java have true multidimensional arrays?


但是通过如下声明二维数组并且不影响数据局部性,是否可以实现同样的效果?

可以。

两个版本之间的数据局部性差异很小,特别是如果我们可以假设N2 相比较大。 (如果我们不能,那么数据局部性很可能是无关紧要的;即性能差异将太小而不会显着。)

Java 以行优先顺序实现多维数组在这里似乎很重要?

这是一个问题吗?如果是的话,那我猜是的。这当然是相关的......虽然如果 Java 实现了它们主要是列,那么你只需翻转行和列并获得等效的解决方案

以这种方式声明数组是否有任何性能优势,或者这是否会降低代码的可读性?

性能问题可能无关紧要。但如果它真的很重要,那么最好的建议是为自己分析和优化代码......在真实的输入数据集上。

至于可读性,这取决于您自己的判断。我无法预测你的代码会是什么样子。


如果您真的想控制内存局部性,那么最好的方法是使用单个一维数组,并以一种总体上为您提供最佳局部性的方式映射索引。 (这取决于您的应用程序以及它如何引用数组中的数据。)

【讨论】:

  • Java 8 仍然如此,还是他们做出了改进?
  • 是的,Java 8 仍然如此。
【解决方案2】:

总结自quick google

“一维数组有通常的对象头。但是,这个对象头是 12 个字节来容纳一个 4 字节的数组长度。然后是数组数据(1 个字节用于布尔值,4 个字节用于引用或原始类型使用)

在 Java 中,多维数组实际上是一组嵌套数组。这意味着二维数组的每一行都有一个对象的开销,因为它实际上是一个单独的对象!”(编辑/解释)

所以本质上,int[2][10] 对 int[2](12 个字节)和每个 int[10] 都有开销。 (2 * 12 字节)。这比您使用的情况多出 12 个字节: 诠释[10]一个; 整数[10] b;

除非您计划使用大量数组,否则这可能永远不会成为问题。我个人会追求可读性,因为这更有可能成为一个问题。事后优化,因为事前优化不太可能产生您期望的结果。

【讨论】:

    【解决方案3】:

    您可以使用java.util 中的众多映射类型之一来实现更好的 OOP 解决方案。

    但是,要在java中创建一个未知长度的数组,你需要使用。

    private int[][] keysAndValues;
    

    然后在你的构造函数中

    this.keysAndValues = new int[2][N];
    

    【讨论】:

    • 谢谢@twinlakes。这在内存中是如何表示的?使用 2-d 与 1d 数组有优势吗?
    • 如果您查看存储在 2D 数组及其等效 1D 数组内存中的字节,它们看起来是一样的。唯一的区别是易于索引。但就像我说的,如果您正在寻找最清晰/简洁的方法,您应该查看 java.util 中的映射类型
    猜你喜欢
    • 2017-01-26
    • 1970-01-01
    • 2016-11-07
    • 2018-05-06
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    相关资源
    最近更新 更多