在Java中,ArrayList
与使用常规数组存储项、使用索引跟踪列表中的项数并在空间用完时自动增加数组大小的类之间有什么根本区别吗?
class myArrayList {
private int[] array = new int[10];
private int itemsInArray = 0;
private void increaseArraySize() {
int[] newArray = new int[array.length + 10];
System.arraycopy(array, 0, newArray, 0, array.length);
array = newArray;
}
public void put(int i) {
if (itemsInArray == array.length)
{
increaseArraySize();
}
array[itemsInArray] = i;
itemsInArray++;
}
public int get(int idx) {
return array[idx];
}
public int size() {
return itemsInArray;
}
}
ArrayList
有一些我的类没有的额外方法(我可以添加),并且实现了List
接口,但除此之外,ArrayList
是否只是为了方便?两者都使用堆存储数据吗?
2条答案
按热度按时间hc2pp10m1#
在Java中,
ArrayList
与使用常规数组存储项、使用索引跟踪列表中的项数并在空间用完时自动增加数组大小的类之间有什么根本区别吗?一般来说,
ArrayList
不是这样的,它只是一个普通的纯Java类,也就是说,没有本地代码,它(粗略地说!)做你的代码所做的事情。但是(正如评论所说)它已经存在了。你不需要设计它,编码它,调试它,调优它......你只需要使用它!
但是,我需要注意的是,您的版本在一些(其他)重要方面与
ArrayList
不同:myArrayList
只保存int
值。它不是泛型的。ArrayList
包含对象,如果你需要一个整数列表,你需要使用Integer
而不是int
作为类型参数(因为Java泛型类就是这样工作的)。myArrayList
中,超出列表末尾的set
调用将使列表增长,它的行为更像动态数组而不是列表。ArrayList
中,超出列表末尾的set
调用将引发异常。如果您想要一个专门用于
int
或其他一些原语类型的Java "list"类型,那么可以使用现有的第三方库;例如GNU Trove库。两者都使用堆来存储数据吗?
是的。事实上,如果你看一下
ArrayList
的源代码,你会发现它做的事情和你的代码做的差不多,但是它做得更"聪明",这将在某些操作中产生更好的"大O"性能。想想这个:
计算复杂度为O(N~2)。
每次调用
list.put(i, 1)
都会引起一个resize,创建一个大小为i
的新数组,然后将i - 1
的值复制到新数组中,这总共是0 + 1 +... N-1或N *(N-1)/2个副本,对于N次调用来说是O(N2)。相比之下,
ArrayList
使用的调整策略是将列表的大小增加到当前大小的50%,如果您进行分析,就会发现对ArrayList.append
的N次调用的平均 * 摊余 * 成本是O(N)...而不是O(N2)。第一课:不要试图重新实现标准的Java实用程序类,这通常是浪费时间,而且很有可能你的努力实际上会使事情变得更糟!
本课也有例外,但您需要丰富的Java编程经验(和/或使用性能分析工具)来识别它们。即使这样,也很有可能存在第三方替代方案来解决问题。
第二课:如果你的目标是理解标准的实用程序类是如何工作的,最好的方法是阅读OpenJDK源代码。它是很好的代码,注解也很好。如果它很复杂,那是有原因的。但是任何有经验的Java程序员如果努力学习,应该都能理解它。
h9vpoimq2#
你问:
在Java中使用ArrayList或动态增长数组有什么区别?
看一看Collections Framework Overview,第一个项目符号表示:
集合框架的主要优点是:
·通过提供数据结构和算法减少编程工作量,这样您就不必自己编写它们。
你问:
在Java中,ArrayList和使用常规数组的类之间有什么根本的区别吗
在行为方面,没有根本的区别。顾名思义,
ArrayList
* 的当前实现是 * 一个使用正则数组的类。所以没有必要自己编写。请记住,
ArrayList
实现的未来版本可以自由地使用实际数组之外的其他方法,前提是满足Javadoc中承诺的契约。ArrayList只是为了方便吗?
是的,如上所述,与其让每个程序员编写自己的实现,为什么不共享一个编写良好、调试良好、文档化良好的实现呢?
大多数Java实现都基于OpenJDK开源代码库,您可以自由地阅读the source code。