如何在java的内存中表示二维数组?

时间:2014-12-14 01:26:41

标签: java arrays multidimensional-array

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

实现此目的的一种方法是为Key和Values声明单独的1-D数组。

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

但通过声明如下所示的二维数组并且不会在数据局部性上妥协,可以实现同样的目标吗?

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

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

3 个答案:

答案 0 :(得分:5)

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

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


  

但通过声明如下所示的二维数组并且不会在数据局部性上妥协,可以实现同样的目标吗?

是的,可以。

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

  

Java在行主要顺序中实现多维数组似乎很重要吗?

这是一个问题吗?如果是,那我想是的。这当然是相关的......虽然如果Java将它们实现为列专业,那么您只需翻转行和列并获得等效的解决方案

  

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

性能问题可能微不足道。但是,如果它确实非常重要,那么最好的建议是为自己配置和优化代码......在REAL输入数据集上。

至于可读性,由你来判断。我无法预测你的代码会是什么样子。


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

答案 1 :(得分:1)

总结来自quick google

“单维数组具有通常的对象标题。但是,此对象标题为12个字节以容纳4字节数组长度。然后是数组数据(布尔值为1个字节,参考值为4个字节或者原始值为多少)类型用途)

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

所以从本质上讲,int [2] [10]有int [2](12字节)的开销,然后是每个int [10]。 (2 * 12字节)。这比你使用时多12个字节: int [10] a; int [10] b;

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

答案 2 :(得分:0)

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

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

private int[][] keysAndValues;

然后在你的构造函数

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