Java 和 C# 中的多维数组

Posted

技术标签:

【中文标题】Java 和 C# 中的多维数组【英文标题】:Multidimensional arrays in Java and C# 【发布时间】:2011-07-15 21:22:31 【问题描述】:

在 C# 中,有两种方法可以创建多维数组。

int[,] array1 = new int[32,32];

int[][] array2 = new int[32][];
for(int i=0;i<32;i++) array2[i] = new int[32];

我知道第一种方法在内部创建一个一维数组,而第二种方法创建一个数组数组(访问速度较慢)。

但是在 Java 中,没有 [,] 这样的东西,我看到多维数组是这样声明的:

int[][] array3 = new int[32][32];

由于这种语法在 C# 中是非法的,而 Java 没有 int[,],我想知道这是否等同于 array1?还是还是数组数组?

【问题讨论】:

另见***.com/questions/168897/… 不,在 c# 中有一种方法可以创建多维数组。另一个创建一个 jagged 数组。它们是两种不同的东西。 【参考方案1】:

它仍然是一个数组数组。只是在 C# 中,您必须在循环中创建每个子数组。所以这个Java:

// Java
int[][] array3 = new int[32][32];

相当于这个C#:

// C#
int[][] array3 = new int[32][];
for (int i = 0; i < array3.Length; i++)

    array3[i] = new int[32];

(正如 Slaks 所说,在 .NET 中,锯齿状数组通常比矩形数组更快。但它们在内存方面的效率较低。)

【讨论】:

【参考方案2】:

你错了;锯齿状(嵌套)数组更快。 (CLR 已针对它们进行了优化)

Java 不支持真正的多维数组;这是一个参差不齐的数组。 Java 语法自动创建所有内部数组;在 C# 中,这需要一个单独的循环。

【讨论】:

嵌套数组基本上比真正的多维数组慢。每个嵌套级别都有一个间接级别(一个额外的指针跟随),并且在大多数情况下不是最佳的内存位置。 @rlibby:你说得对,它们比一维数组慢。但是,.Net 2d 数组的效率较低。 (请注意,我没有测量过) 我刚刚做了一个快速基准测试,在 C# 中,迭代一个二维数组(例如int[x, y])所需的时间大约是迭代一个相同大小的一维数组的两倍。幸好 18 个月的摩尔定律解决了这个问题。 :) 我没有将二维数组与锯齿状数组进行比较。 @rlibby:CLR 中有两种类型的数组:vectors(始终从零开始和一维)和 arrays(它们可能是多维的并且可能没有零基数)。我怀疑是额外的“它可能没有零基”算术在这里有所作为。不过只是猜测。 @Hannesh:它们在 .Net 的实现中速度较慢。它们本质上并不慢。它们速度较慢/不支持的原因是它们的使用不多。【参考方案3】:

由于人们担心 .NET 中多维数组与交错数组的性能,我实施了一些测试,并在 8k x 8k 元素上对结果进行了基准测试:

测试是:

    多维二维数组 多维索引向后(y 优先) 使用 GetLength(x) 而不是整数边界的多维 与向后的索引交错 交错 一维(大小 x 大小)与索引中的乘法 带增量索引的一维

结果:

one <> Elapsed Time: 0.543558s
two <> Elapsed Time: 0.8911516s
three <> Elapsed Time: 0.8908123s
four <> Elapsed Time: 1.1367238s
five <> Elapsed Time: 0.3039648s
six <> Elapsed Time: 0.8110969s
seven <> Elapsed Time: 0.2629394s

为了好玩,我也在 WP7 模拟器上运行了它们,得到了相似的数字。

测试函数代码为here。

【讨论】:

您的第六次测试不正确(根据您的测试描述),因为您使用 x + ysize 作为偏移量,从而在数组中跳跃。偏移量当然应该是 xsize + y。【参考方案4】:

在 Java 中,您要声明一个数组数组。

您可以通过以下代码看到这一点:

int[][] arrOfArr = new int[5][];
arrOfArr[0] = new int[5];
arrOfArr[1] = new int[1];
arrOfArr[2] = new int[9];
...

int[][] arr = new int[3][3]; 只是以下的简写:

int[][] arr = new int[3][];
arr[0] = new int[3];
arr[1] = new int[3];
arr[2] = new int[3];

【讨论】:

【参考方案5】:

我正在将一些 Java 代码翻译成 C# - 这就是我如何处理 Jagged 数组

    //Java
    private static int grad3[][] = 1,1,0,-1,1,0,1,-1,0,-1,-1,0,1,0,1,-1,0,1,1,0,-1,-1,0,-1,0,1,1,0,-1,1,0,1,-1,0,-1,-1;

    //C#
    private static int[,] grad3setup =   1, 1, 0 ,  -1, 1, 0 ,  1, -1, 0 ,  -1, -1, 0 ,  1, 0, 1 ,  -1, 0, 1 ,  1, 0, -1 ,  -1, 0, -1 , 
                                   0, 1, 1 ,  0, -1, 1 ,  0, 1, -1 ,  0, -1, -1  ;

    private static int[][] grad3
    
        get
        
            int[][] grad3 = new int[12][];
            for (int i = 0; i < grad3.Length; i++)
            
                grad3[i] = new int[3]  grad3setup[i, 0], grad3setup[i, 1], grad3setup[i, 2] ;
            
            return grad3;
        
    

【讨论】:

【参考方案6】:

它是一个数组数组,具有与 C# 中相同的性能折衷。 如果您知道您的数组数组不会是锯齿状的,那么您可以将它包装在一个类中,以便在一维支持数组上获得二维索引。

【讨论】:

以上是关于Java 和 C# 中的多维数组的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的多维数组列表或列表?

C# 中的多维关联数组

如何从 C# 中的嵌套循环写入多维数组?

从共享 ArrayPool 中租用和返回 C# 中的多维数组的正确方法?

C#如何写一个多维数组

从C#中的另一个类访问多种类型的多维数组