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

Java 为什么我会使用传统的数组而不是ArrayList对象?,java,arrays,arraylist,Java,Arrays,Arraylist,我能想到的唯一原因是常规数组使用更少的内存(尽管它可能可以忽略不计),并且可以存储原语。即使这样,您也可以只使用包装器类 它使用更少的空间 更快 它可以存储原语 它强制执行定义的大小,这有助于错误查找 对于初学者来说,常规数组确实使用更少的内存,因为它们是按所需的确切大小创建的,而ArrayList可能会浪费多达一半的容量,如果ArrayList足够大,这是不可忽略的 此外,对数组中元素的访问速度更快,因为它不需要调用get()和类似的方法:直接访问内存 最后但并非最不重要的一点是,创建的数组的

我能想到的唯一原因是常规数组使用更少的内存(尽管它可能可以忽略不计),并且可以存储原语。即使这样,您也可以只使用包装器类

  • 它使用更少的空间
  • 更快
  • 它可以存储原语
  • 它强制执行定义的大小,这有助于错误查找
  • 对于初学者来说,常规数组确实使用更少的内存,因为它们是按所需的确切大小创建的,而ArrayList可能会浪费多达一半的容量,如果ArrayList足够大,这是不可忽略的

    此外,对数组中元素的访问速度更快,因为它不需要调用
    get()
    和类似的方法:直接访问内存


    最后但并非最不重要的一点是,创建的数组的类型完全正确(即使是基本类型,也不能直接存储到ArrayList中),而ArrayList始终是隐藏在引擎盖下的
    对象[]
    ,提取每个元素所需的额外演员阵容将受到性能惩罚。

    除了涵盖功能方面的两个已经很好的答案之外,我认为不应该忘记可读性

    如果你有一个超过一维的字符串数组,比如说三个,你不必写

    List<List<List<String>>> stringCube = new ArrayList<List<List<String>>>;
    // all the initialization
    
    甚至

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

    在使用(数组)列表时,不能这么短。对象创建和方法调用非常昂贵。如果您真的需要优化(例如游戏),原始数据结构会有所帮助

    这里有一个小程序来说明速度差。在我的系统上,用100万整数填充基本阵列大约需要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) );
    }
    
    static int SIZE=1000000;
    公共静态void main(字符串[]args)
    {
    长t0=System.currentTimeMillis();
    int[]myInts=新的int[SIZE];
    对于(int i=0;i
    您可以将原语存储在ArrayList中。@clcto:是的,您可以,但是当您尝试使用
    ArrayList.get(someDouble)
    时,除非您将其包装,否则它将不起作用,因为它是一个对象。除了各种可能的减速外,ArrayList由数组支持这一事实本身可能是有启发性的。虽然从理论上讲,数组可以更快,一般来说,我认为这些差异可以忽略不计。+1除此之外,在处理本机代码时需要使用数组。get()上的一条注释:ArrayList.get()也可以转换为直接内存访问(但是,是的,您确实会受到方法调用的惩罚)@MrBackend一切最终都会转化为内存访问:)但我的观点是,至少还涉及到一个额外的方法调用,如果我们考虑ArrayList层次结构中的抽象类,可能会更多。当JIT编译器启动时,其中一些调用将得到优化。。。与简单的
    array[index]
    调用相比,这会带来很多麻烦。
    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) );
    }