我为什么要使用传统数组而不是ArrayList对象?

3
我能想到的唯一原因是,普通数组使用的内存较少(尽管这可能可以忽略不计),并且可以存储基本类型。即便如此,您仍然可以使用包装类。

1
你可以将基本类型存储在ArrayList中。 - clcto
@clcto:是的,你可以这样做,但是当你尝试使用ArrayList.get(someDouble)时,它不会起作用,除非你将其包装起来,因为它是一个对象。 - Coffee Maker
1
除了各种可能的减速之外,ArrayList由数组支持这一事实本身就具有暗示意义。 - clwhisk
4个回答

12

常规数组在一开始使用的内存量较少,因为它们创建时大小正好符合需求,而ArrayList可能会浪费多达一半的容量,如果ArrayList足够大,则这不可忽略。

此外,访问数组中的元素更快,因为不需要调用get()等方法:这是直接的内存访问。

最后但并非最不重要的是,数组是以确切的正确类型创建的(甚至是原始类型,这些类型无法直接存储到ArrayList中),而ArrayList始终是Object[],对于提取每个元素所需的额外强制转换将导致性能损失。


2
除此之外,在处理本地代码时,您需要使用数组。 - Rohit Jain
get()方法的一个评论:ArrayList.get()也可以理解为直接内存访问(但是是的,你确实会受到方法调用的惩罚)。 - MrBackend
@MrBackend “一切”最终都会转化为内存访问 :) 但我的观点仍然成立,至少涉及到一个额外的方法调用,如果我们考虑ArrayList层次结构中的抽象类,则可能涉及更多。当JIT编译器启动时,其中一些调用将被优化掉...与简单的array[index]调用相比,这是很麻烦的。 - Óscar López

4
  1. 它使用更少的空间
  2. 它更快
  3. 它可以存储基本数据类型
  4. 它强制定义大小,有助于排查错误

1
虽然数组理论上可能更快,但通常我认为差异将是微不足道的。 - Andrew

2
除了两个已经很好地回答了功能方面的问题,我认为可读性也不应该被忽视。
如果您有一个多维字符串数组,比如三维数组,您不必编写以下代码:
List<List<List<String>>> stringCube = new ArrayList<List<List<String>>>;
// all the initialization

当你可以做到

String[][][] stringCube = new String[2][2][2];

甚至更多
String[][][] stringCube = {{{"000"},{"001"}},
                           {{"010"},{"011"}},
                           {{"100"},{"101"}},
                           {{"110"},{"111"}}};

当使用(数组)列表时,您无法这样缩短代码。

1

速度。创建对象和方法调用是昂贵的。如果你真的需要优化(例如游戏),原始数据结构可以帮助。

这里有一个小程序来说明速度差异。在我的系统上,用100万个int填充原始数组大约需要5毫秒。填充对象列表大约需要150毫秒。

static int SIZE = 1000000;

public static void main(String[] args)
{
    long t0 = System.currentTimeMillis();
    int[] myInts = new int[SIZE];
    for (int i = 0; i < SIZE; i++ )
    {
        myInts[i] = i;
    }
    long t1 = System.currentTimeMillis();
    List<Integer> myList = new ArrayList<Integer>();
    for (int i = 0; i < SIZE; i++ )
    {
        myList.add( i );
    }
    long t2 = System.currentTimeMillis();
    System.out.println( "primitive array time: " + (t1-t0) );
    System.out.println( "object list time: " + (t2-t1) );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接