为啥 ArrayLists 的 ArrayList 不是多维的?

Posted

技术标签:

【中文标题】为啥 ArrayLists 的 ArrayList 不是多维的?【英文标题】:Why is an ArrayList of ArrayLists not multidimensional?为什么 ArrayLists 的 ArrayList 不是多维的? 【发布时间】:2017-10-07 05:19:20 【问题描述】:

我最近参加了一次面试,面试官问我一个关于ArraysArrayList 的问题。

他问我一个数组数组是否可以是多维的,那为什么ArrayList的一个ArrayList不是多维的?

例如:

// Multidimensional
int[][] array = new int[m][n]; 

// Not multidimensional
ArrayList<ArrayList<Integer>> seq = new ArrayList<ArrayList<Integer>>(); 

谁能帮我理解这个?

【问题讨论】:

@MichaelMarkidis 并非所有数组都必须具有相同的大小。 其实java没有true二维数组,它们是作为数组的数组来实现的,但是当人们说它是二维的时候我可以理解... @Aominè 真正的二维数组是什么意思? "A 二维ArrayList" 表示存在一个 ArrayList。同样的论点也适用于数组……但由于 Java 对它们有特殊的语法,人们经常将多维数组视为单个对象(实际上并非如此)。 在我看来,这是一个非常愚蠢的面试问题。对于所有意图和目的,List&lt;List&lt;Integer&gt;&gt; 是一个二维数组:您可以将其可视化为存在于二维中。如果您想明确说明非锯​​齿状,则“矩阵”一词可以更好地传达该含义。这是故意设计来绊倒你的。 【参考方案1】:

ArrayList 是List 的实现。这是一个使用数组实现的List。数组的使用是一个实现细节。 list interface 不支持多维列表的概念,因此您也不希望 ArrayList 支持。此外,它没有作为traditional list data structure 的用例来处理。

数组支持多维,因为它是 Java 的语言特性。

【讨论】:

为什么不支持维度列表? List 作为数据结构不涉及维度用例en.wikipedia.org/wiki/List_(abstract_data_type) 不是我的反对意见,但我怀疑这是因为在 Java 中数组不是多维的——它们是数组的数组。【参考方案2】:

从另一面来看:您可以像使用“多维”数组一样使用列表。您只需将array[row][column] 替换为someList.get(row).get(column)

最后,java 数组以类似的方式实现:两个暗矩阵也只是一个暗数组的一个暗数组!换句话说:差异更多是在表面上,而不是深层次的概念原因!

更准确地说:Java 类型系统允许您输入Object[][],所以从这个意义上说,它知道Object[][] 的类型;但如前所述,实际上,没有多维数组;正如 Java 将“两个暗淡”的东西视为对数组的引用的数组!

另一方面:“多维数组”有一定的概念,例如JVM specification 明确提到:

multianewarray 指令的第一个操作数是要创建的数组类类型的运行时常量池索引。第二个是实际创建的该数组类型的维数。 multianewarray 指令可用于创建类型的所有维度,如 create3DArray 的代码所示。请注意,多维数组只是一个对象,因此分别由 aload_1 和 areturn 指令加载和返回。

【讨论】:

java 类型系统不支持多维数组。它支持数组的数组,这是一个不同的概念。 @PeteKirkham 所以Object[][] 不是不同于Object[]Object 的类型?但我明白你的意思......我希望我对答案的编辑在这里有所帮助。 它们是不同的类型,Object[][] 是(对象数组)的数组,而Object[] 是对象数组,就像int[]int 是不同的类型一样。如果 java 支持多维数组,Object[,] 将再次成为不同的类型。有关具有多维数组的 C#,请参阅 ***.com/questions/597720。 你可以使用专门的操作来让一个对象像一个多维数组,就像multianewarray 指令,它允许一个有效的实现,例如Object[][] array=new Object[3][4];,但它不会阻止完全不同的用法,例如你可以在实例化之后说array[1]=null 和/或array[0]=array[2];,创建一个甚至远不像多维数组的数据结构。【参考方案3】:

我将在这里勉强回答这个问题,但是对于这个广泛的问题没有正确答案。

我们首先要问,是什么让数组成为多维的?

我将假设您的面试官考虑一个具有固定大小的多维数组(如您在问题中所示),不能将其视为“锯齿状”。根据微软的说法,C#中的jagged数组如下:

交错数组的元素可以有不同的维度和大小。

在 Java 中,多维数组只是一个数组,其中每个元素也是一个数组。这些数组必须定义为固定大小,以便在其中对元素进行索引,但锯齿状数组可以具有不同的大小,如上所述。

ArrayList 由数组支持;但是,当向其中添加一定数量的元素时,数组会扩展。由于这个原因,ArrayList 可能会变得参差不齐,并且可以不再被认为是多维的。

编辑:在重读了几遍之后,我确定你的面试官只是想迷惑你。老实说,一种数据类型(数组)是多维的,而另一种数据类型(使用数组的ArrayList)不是多维的,这确实没有意义。

【讨论】:

是的,多维数组的大小是固定的。我也认为由于锯齿状的性质,arraylist 不能是多维的。是的,你是对的,也许他是想迷惑我,他又把事情搁置了半个小时。 我可以有效地调整多维数组的子数组大小,即array[index]=Arrays.copyOf(array[index], newSize);【参考方案4】:

Cay S. Horstmann 在他的著作 Core Java for the impatient 中说过:

Java 中没有二维数组列表,但你可以声明一个 ArrayList&lt;ArrayList&lt;Integer&gt;&gt; 类型的变量并建立行 自己。

由于ArrayLists是可以伸缩变锯齿而不是多维的,可以说它不是二维数组,多维的意思固定行和列,因此我也在 cmets 中声明 Java 没有 true 多维数组,但这超出了您的问题范围。

如果你好奇我为什么说 Java 没有 true 多维数组,请阅读 the differences between a multidimensional array and an array of arrays in C#?


只是为了让我的答案更清楚,关于 Java 是否有 true 多维数组,我确实 not 说 java 没有多维数组,我说 Java 没有 true 多维数组,正如 JLS 所说的那样:

一个多维数组不需要有相同长度的数组 每个级别。

【讨论】:

拥有不同长度的子数组并不是令人兴奋的部分。更有趣的是,多维数组是一个引用数组,可能是null或者指向同一个数组。对于Object[][]…,数组甚至可以包含对自身的引用。【参考方案5】:

出于同样的原因,我将所有备用购物袋放入的购物袋不是多维购物袋。

如果我把一个坚果放在一个袋子里,然后把那个袋子放在另一个袋子里,我必须执行两次操作才能得到坚果。

如果我将螺母放在二维组件托盘中,我可以使用两个索引执行一个操作来访问它:

source

类似地,列表列表(或数组数组)和真正的二维数组之间存在根本区别 - 采用两个索引的单个操作用于访问二维数组中的元素,两个操作分别采用一个索引用于访问列表列表中的元素。

ArrayList 有一个索引,所以它的秩为 1。二维数组有两个索引,它的秩为 2。

注意:我所说的“二维数组”不是指 Java 数组(引用)数组,而是指在 FORTRAN 等其他语言中发现的二维数组。 Java 没有多维数组。如果你的面试官特别提到 Java 的“数组数组”,那么我会不同意它们,因为 Java 的 int[][] 定义了一个对整数数组的引用数组,这需要两个取消引用操作来访问这些元素。例如,C 中的数组数组支持使用单个解引用操作进行访问,因此更接近于多维情况。

【讨论】:

您在哪一方面声明array[index1][index2] 是一个单一的操作,而list.get(index1).get(index2) 是两个?无论哪种情况,我都可以将其拆分为两个操作,例如tmp=array[index1]; result=tmp[index2]; @Holger 我认为这里的重点是Java 不支持多维数组。它具有数组数组 - 与列表列表没有什么不同。我认为在这种情况下,面试官是错误的——也许是问了一个引导性问题。 @Boris the Spider:我知道,但这个答案似乎有所不同…… @Holger 数组数组(与 Java 对数组的引用数组相反)可以实现为乘法和单个相对提取。 这个问题显然是 Java 特有的。如果您指的是非 Java 数组,您应该在回答中指出这一点。【参考方案6】:

因为它根本不是立体的。它是一个带有 API 的对象。多维的任何外观都是由它的 API 提供的,但它纯粹是在旁观者的眼中。另一方面,数组是多维的,因此也可以是多维的。

【讨论】:

在上面的cmets中提到java中没有真正的二维数组【参考方案7】:

面试官的说法是荒谬的。

正如您在本页中看到的那样,有人可能会争辩说,Java 没有真正的多维数组,在这种情况下,它也没有多维 ArrayList。另一方面,它当然允许您以相同的方式通过数组和 ArrayList 表示多维结构。

定义两者之间的主要区别是相当武断且毫无意义的。

可能面试官只是想开始一场技术辩论,以测试你解释细节的能力。

【讨论】:

+1 仅用于最后一句话。这类问题对了解应聘者的技术知识深度很有帮助。

以上是关于为啥 ArrayLists 的 ArrayList 不是多维的?的主要内容,如果未能解决你的问题,请参考以下文章

从ArrayLists的ArrayList中删除重复项[重复]

将arraylists1和arraylist2之间相等的自定义对象移除到arraylist1中

在 ArrayLists () 中放入啥 [关闭]

使用方法在 ArrayLists 中循环

为啥 Java 不为 ArrayLists 实现 last() 方法? [关闭]

Java Swing 显示来自 ArrayLists 的大量数据