为啥 ArrayLists 的 ArrayList 不是多维的?
Posted
技术标签:
【中文标题】为啥 ArrayLists 的 ArrayList 不是多维的?【英文标题】:Why is an ArrayList of ArrayLists not multidimensional?为什么 ArrayLists 的 ArrayList 不是多维的? 【发布时间】:2017-10-07 05:19:20 【问题描述】:我最近参加了一次面试,面试官问我一个关于Arrays
和ArrayList
的问题。
他问我一个数组数组是否可以是多维的,那为什么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<List<Integer>>
是一个二维数组:您可以将其可视化为存在于二维中。如果您想明确说明非锯齿状,则“矩阵”一词可以更好地传达该含义。这是故意设计来绊倒你的。
【参考方案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<ArrayList<Integer>>
类型的变量并建立行 自己。
由于ArrayList
s是可以伸缩变锯齿而不是多维的,可以说它不是二维数组,多维的意思固定行和列,因此我也在 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中