在Java中,我应该使用ArrayList <long>还是long []?</long>

时间:2012-12-26 06:54:08

标签: java arrays performance arraylist

我正在编写一个程序,它接受400个long类型的数字,并会根据运行时的条件修改其中一些,我想知道是使用ArrayList<Long>还是long[]

使用哪个会更快?我正在考虑使用long[]因为大小是固定的。

6 个答案:

答案 0 :(得分:17)

当大小固定时,long[]更快,但它允许可维护性较低的API,因为它没有实现List接口。

注意long[]速度更快有两个原因:

  1. 使用原始long而不是框对象Long s(也可以实现更好的缓存性能,因为long是有条件分配的,Long不是保证)
  2. 数组更简单,效率更高DS。
  3. 然而,为了更简单的可维护性 - 我会使用List<Long>,除非性能在程序的这一部分非常关键。

    如果你经常在紧密的循环中使用这个集合 - 而你的探查器说它确实是一个瓶颈 - 那么我会转而使用效率更高的long[]

答案 1 :(得分:8)

就速度而言,400项的清单几乎无关紧要。如果您需要动态扩展列表,ArrayList<Long>会更好;如果大小是固定的,long[]可能会更好(并且更快一点,但在大多数情况下你可能不会注意到差异)。

答案 2 :(得分:4)

在其他答案中没有提到的事情很少:

  • 泛型集合实际上是Object的集合,或者更好地说,这就是Java编译器将使用的集合。这是long[]始终保持原样。

  • 第一个要点的结果是,如果你做了一些事情,最终将Long以外的东西放入你的集合中,在某些情况下编译器会让它通过(因为Java类型系统不健全) ,例如,它将允许你向上转换,然后重新转换为完全不同的类型。)

  • 这两者的一个更普遍的结果是Java泛型是半生不熟的,在一些不那么微不足道的情况下,如反射,序列化等可能会“惊讶”你。事实上,使用普通数组然后使用泛型更安全。


package tld.example;

import java.util.List;
import java.util.ArrayList;

class Example {

    static void testArray(long[] longs) {
        System.out.println("testArray");
    }

    static void testGeneric(List<Long> longs) {
        System.out.println("testGeneric");
    }

    @SuppressWarnings("unchecked")
    public static void main(String... arguments) {
        List<Long> fakeLongs = new ArrayList<Long>();
        List<Object> mischiefManaged = (List<Object>)(Object)fakeLongs;
        mischiefManaged.add(new Object());
        // this call succeeds and prints the value.
        // we could sneak in a wrong type into this function
        // and it remained unnoticed
        testGeneric(fakeLongs);

        long[] realLongs = new long[1];
        // this will fail because it is not possible to perform this cast
        // despite the compiler thinks it is.
        Object[] forgedLongs = (Object[])(Object)realLongs;
        forgedLongs[0] = new Object();
        testArray(realLongs);
    }
}

这个例子有点做作,因为很难想出一个简短令人信服的例子,但相信我,在不那么微不足道的情况下,当你必须使用反射和不安全的演员时,这是非常有可能。

现在,你必须考虑除了合理的,还有一个传统。每个社区都有一套习俗和传统。有许多肤浅的信仰,例如在这里表达的那些信仰。当有人声称实施List API是一种无条件的善意,如果这种情况没有发生,那么它一定是坏事......这不仅仅是一种支配性的观点,这是绝大多数Java程序员所相信的。毕竟, 并不重要,Java作为一种语言还有很多其他缺点......所以,如果你想确保你的面试或者只是避免与其他人发生冲突无论什么原因,Java程序员都会使用Java泛型。但如果你不喜欢它 - 好吧,也许只是使用其他语言;)

答案 3 :(得分:2)

long []速度更快,内存更少。阅读“Effective Java”第49项:“将原始类型更喜欢盒装基元”

答案 4 :(得分:2)

我认为最好使用ArrayList,因为在长时间运行中维护要容易得多。将来,如果数组的大小增加到400以上,那么维持long []会产生大量开销,而ArrayList会动态增长,因此您无需担心增加的大小。
此外,ArrayList的处理方式比静态数组(long [])更好地处理,因为它们会自动重新组织元素,使它们仍然显示为有序元素。 静态数组在这方面更糟糕。

答案 5 :(得分:0)

为什么不使用处理原始类型的众多列表实现之一?例如TLongArrayList。它可以像Javas List一样使用,但基于long []数组。所以你有双方的优势。

HPPC简要概述了一些库:https://github.com/carrotsearch/hppc/blob/master/ALTERNATIVES.txt