我正在尝试使用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在行主要顺序中实现多维数组似乎很重要吗?以这种方式声明数组是否有任何性能优势,或者这是否会降低代码的可读性?
答案 0 :(得分:5)
Java中的2D数组实际上是一个对象引用数组,每个对象引用都指向一维数组。 2D数组和每个1D数组都是独立的堆对象,并且(理论上)可以在堆中的任何位置。
(有关原因的讨论,请参阅:Why doesn't Java have true multidimensional arrays?)
但通过声明如下所示的二维数组并且不会在数据局部性上妥协,可以实现同样的目标吗?
是的,可以。
两个版本之间的数据位置差异很小,特别是如果我们可以假设N
与2
相比较大。 (如果我们不能,那么数据局部性很可能是不相关的;即性能差异太小而不显着。)
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];