【问题标题】:Why would I ever use a traditional array rather than an ArrayList object?为什么我会使用传统数组而不是 ArrayList 对象?
【发布时间】:2013-10-28 21:00:13
【问题描述】:

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

【问题讨论】:

  • 您可以将基元存储在 ArrayList 中。
  • @clcto:是的,你可以,但是当你尝试使用ArrayList.get(someDouble) 时,除非你包装它,否则它将无法工作,因为它是一个对象。
  • 除了各种可能的减速之外,ArrayList 由数组支持这一事实可能具有暗示性。

标签: java arrays arraylist


【解决方案1】:

常规数组确实使用较少的内存,因为它们是按所需的确切大小创建的,而 ArrayList 可能会浪费其容量的一半,如果ArrayList 已经够大了。

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

最后但并非最不重要的一点是,数组是由精确、正确的类型(甚至是原始类型,不能直接存储到 ArrayList 中)创建的,而 ArrayList 在底层始终是 Object[],并且提取每个元素所需的额外演员表将会有性能损失。

【讨论】:

  • +1 除此之外,您在使用原生代码时需要使用数组。
  • 关于 get() 的一条评论:ArrayList.get() 也可以转换为直接内存访问(但是是的,您确实会受到方法调用的惩罚)
  • @MrBackend everything 最终转化为内存访问 :) 但我的观点是,至少涉及一个额外的方法调用,如果我们可能会更多考虑到 ArrayList 层次结构中的抽象类。当 JIT 编译器启动时,其中一些调用将得到优化……与简单的 array[index] 调用相比,这很麻烦。
【解决方案2】:
  1. 占用的空间更少
  2. 更快
  3. 可以存储原语
  4. 它强制执行定义的大小,这有助于发现错误

【讨论】:

  • 虽然理论上数组可以更快,但一般我认为差异可以忽略不计。
【解决方案3】:

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

如果你有一个多于一维的字符串数组,比如三个,你不必写

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"}}};

在使用 (Array)List 时您不能这样做。

【讨论】:

    【解决方案4】:

    速度。对象创建和方法调用很昂贵。如果您确实需要优化(例如游戏),原始数据结构可以提供帮助。

    这里有一个小程序来说明速度差异。在我的系统上用 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) );
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-10
      • 2010-10-15
      • 2021-07-11
      • 2011-10-06
      • 2017-06-24
      • 2013-05-18
      • 1970-01-01
      • 2020-02-03
      • 1970-01-01
      相关资源
      最近更新 更多