【问题标题】:Are there reasons to prefer Arrays over ArrayLists? [duplicate]是否有理由更喜欢 Arrays 而不是 ArrayLists? [复制]
【发布时间】:2011-06-18 02:11:51
【问题描述】:

可能重复:
Benefits of arrays

你好,

有什么理由更喜欢Arrays (MyObject[]) 而不是ArrayLists (List<MyObject>)?唯一可以使用数组的地方是原始数据类型(int、boolean 等)。但是我对此没有合理的解释,它只是使代码更苗条。

一般来说,我使用 List 是为了保持更好的灵活性。但是还有理由使用真正的数组吗?

我想知道, 最好的问候

【问题讨论】:

  • Benefits of arrays 的可能副本。一般来说,您已经在这里找到了很多 ArrayList 与 Array 的问题。
  • 为什么不合并删除这个呢?

标签: java arrays list arraylist


【解决方案1】:

每当我知道我只会使用固定数量的元素时,我更喜欢使用Arrays 而不是ArrayLists。我的理由大多是主观的,但我还是在这里列出它们:

  1. Collection 类用于基元会明显变慢,因为它们必须使用自动装箱和包装器。

  2. 比起ArrayListget(),我更喜欢更直接的[] 语法来访问元素。当我需要多维数组时,这确实变得更加重要。

  3. ArrayLists 通常会提前分配大约两倍的内存,以便您可以非常快速地追加项目。因此,如果您不再添加任何项目,就会产生浪费。

  4. (可能与上一点有关)我认为ArrayList 访问通常比普通数组慢。 ArrayList 实现使用底层数组,但所有访问都必须通过 get()set()remove() 等方法,这意味着它通过的代码比简单的数组访问要多。但我没有实际测试过差异,所以我可能错了。

话虽如此,我认为选择实际上取决于您的需要。如果您需要固定数量的元素,或者要使用多个维度,我建议您使用普通数组。但是,如果您需要一个简单的随机访问列表并且要对其进行大量插入和删除,那么使用Arraylist 会更有意义

【讨论】:

    【解决方案2】:

    通常数组有其问题,例如类型安全:

    Integer[] ints = new Integer[10];
    Number[] nums = ints; //that shouldn't be allowed
    nums[3] = Double.valueOf[3.14]; //Ouch!
    

    他们也不擅长收藏。所以一般来说,你应该更喜欢集合而不是数组。只有几件事数组可能更方便。正如您已经说过的原始类型将是一个原因(尽管您可以考虑使用类似集合的库,如Trove)。如果数组隐藏在对象中并且不需要更改其大小,则可以使用数组,特别是如果您需要可以获得所有性能(例如用于 3D 图形的 3D 和 4D 向量和矩阵)。使用数组的另一个原因可能是您的 API 有很多可变参数方法。

    顺便说一句:如果您需要匿名类的可变变量,使用数组有一个可爱的技巧:

    public void f() {
       final int[] a = new int[1];
       new Thread(new Runnable() {
          public void run() {
             while(true) {
                System.out.println(a[0]++);
             }
          }    
       }).start();  
    }
    

    请注意,您不能对 int 变量执行此操作,因为它必须是 final。

    【讨论】:

      【解决方案3】:

      我认为数组和列表的主要区别在于,数组具有固定长度。一旦它满了,它就满了。 ArrayLists 具有灵活的长度,并且确实使用数组来实现。当 arrayList 容量不足时,数据会被复制到另一个容量更大的数组中(这是我曾经教过的)。

      如果您的数据长度固定,则仍然可以使用数组。因为数组非常原始,所以它们没有太多可以调用的方法。使用这些数组的优势不再那么大了,因为 arrayLists 只是你在 Java 或任何其他语言中想要的东西的很好的包装器。

      我认为现在您甚至可以为数组列表设置固定容量,因此即使这种优势也消失了。

      那么有什么理由喜欢它们吗?不,可能不是,但由于基本功能,它确实确保您的内存中只有一点空间。 arraylist 是一个非常大的包装器,并且具有很大的灵活性,这是您并不总是想要的。

      【讨论】:

      • >"arraylist 是一个非常大的包装器,并且具有很大的灵活性,你并不总是想要什么。?很多额外未使用的空间。
      • @bestsss ArrayLists 创建具有额外容量的数组。所以是的,使用了额外的空间,这可能一开始就不需要。根据您放入 arraylist 的对象类型,arraylist 会因额外容量而变大。
      • >根据您放入数组列表的对象类型,数组列表会因额外容量而变大stackoverflow.com/questions/4739947/…
      【解决方案4】:

      给你一个:

      排序列表(通过 j.u.Collections)首先转换为 [],然后排序(再次克隆 [] 以进行合并排序),然后放回列表。 您确实了解 ArrayList 在封面下有一个支持 Object[] 。

      过去有一个案例 ArrayList.get 没有被 -client 热点编译器内联,但现在我认为这已经解决了。因此,与 Object[] 相比,使用 ArrayList 的性能问题并不那么棘手,将 case 转换为适当的类型仍然需要几个时钟(但应该是 CPU 预测时间的 99.99%);访问 ArrayList 的元素可能会花费更多的缓存未命中等(或主要是第一次访问)

      所以它确实取决于你最终用你的代码做什么。

      编辑 忘记了您可以 atomic 访问数组的元素(即 CAS 的东西),一个 impl 是 j.u.c.atomic.AtomicReferenceArray。这不是最实用的,因为它不允许对 Objec[][] 进行 CAS,但 Unsafe 可以解决问题。

      【讨论】:

        猜你喜欢
        • 2011-03-18
        • 2011-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-06
        • 2016-09-24
        • 2011-05-13
        相关资源
        最近更新 更多