收集与阵列性能明智

时间:2012-12-17 08:13:33

标签: java

请您告诉我表现明智为什么数组优于收藏

5 个答案:

答案 0 :(得分:7)

不是。它实际上取决于你对容器的使用。

某些算法可能在阵列上的O(n)中运行,而在另一个集合类型(实现Collection接口)上的O(1)中运行。

  • 考虑删除某个项目。在这种情况下,即使是本机类型,该数组的执行速度也比链接列表及其方法调用(在某些VM上无论如何都可以内联)要慢:它在O(n)VS O(1)中运行以进行链接列表
  • 考虑搜索元素。它在0(n)中运行,用于树的数组VS O(log n)。

某些Collection实现使用数组来存储它们的元素(我认为是ArrayList),因此在这种情况下性能不会有太大差异。

你应该花时间优化你的算法(并利用各种可用的集合类型),而不是担心数组VS Collection的利弊。

答案 1 :(得分:3)

许多集合都是数组的包装器。这包括ArrayList,HashMap / Set,StringBuilder。对于优化的代码,操作的性能差异是最小的,除非您进行更适合该数据结构的操作,例如查找Map比在数组中查找要快得多。

对基本原语的集合使用泛型可能会更慢,不是因为集合较慢而是额外的对象创建和缓存使用(因为所需的内存可能更高)这种差异通常太小而无关紧要但如果你是关注这一点,您可以使用Trove4J库,它们是基元数组的包装器而不是对象数组。

如果集合较慢,那么当您使用不适合的操作时,例如随机访问LinkedList,但合理的编码可以避免这些情况。

答案 2 :(得分:0)

基本上,因为数组是Java中的原始数据结构。对它们的访问可以直接转换为本机内存访问指令而不是方法调用。

尽管如此,在所有情况下,数组都将严格地超越集合并不是很明显。如果您的代码引用了集合变量,其中运行时类型可以在JIT时间单态地知道,Hotspot将能够内联访问方法,并且它们很简单,可以同样快,因为无论如何基本上没有开销。

然而,许多集合的访问方法本质上比数组引用更复杂。例如,无论Hotspot对其进行多少优化,HashMap都无法像简单的数组查找一样高效。

答案 3 :(得分:0)

你无法比较这两者。 ArrayList是一个实现,Collection是一个接口。 Collection接口可能有不同的实现。

在实践中,选择实现作为对数据的简单访问。通常是ArrayList,如果你需要遍历所有元素。如果您需要按键访问,则可以使用Hashtable。

只有在进行测量后才应考虑性能。然后很容易改变实现,因为集合框架有像Collection接口这样的通用接口。

答案 4 :(得分:0)

问题是使用哪一个以及何时使用?

数组基本上是固定大小的元素集合。关于数组的坏处是它不可调整大小。但是如果你清楚你的元素大小,它的恒定大小可以提供效率。因此,当您知道可用的元素数量时,最好使用数组。

<强>集合

ArrayList 是另一个可以调整元素数量的集合。因此,如果您不确定集合中的元素数量,请使用ArrayList。但是使用ArrayLists时需要考虑一些事实。

  • ArrayLists未同步。所以如果有多个线程 访问和修改列表,然后可能同步 需要在外部处理。

  • ArrayList在内部实现为数组。所以每当一个新的 添加了一个n + 1个元素的数组,然后创建所有元素 n个元素从旧数组复制到新数组然后 新元素插入到新数组中。

  • 按时添加n个元素。

  • isEmpty,size,iterator,set,get和listIterator操作
    需要相同的时间,与您访问的元素无关。

  • 只能将对象添加到ArrayList

  • 允许空元素

如果需要向ArrayList添加大量元素,可以使用ensureCapacity(int minCapacity)操作来确保ArrayList具有所需的容量。这将确保在添加所有元素时仅复制Array一次,并增加向ArrayList添加元素的性能。另外,在1000个元素的中间插入一个元素,需要向上或向下移动500个元素,然后在中间添加元素。

使用ArrayList的好处是访问随机元素很便宜,并且不受ArrayList中元素数量的影响。但是在尾部或中间添加元素是昂贵的。

Vector 与ArrayList类似,区别在于它是同步的。它提供了一些其他好处,例如它具有初始容量和增量容量。因此,如果向量的容量为10且增量容量为10,那么当您添加第11个元素时,将使用20个元素创建新的Vector,并将11个元素复制到新的Vector。因此,添加第12到第20个元素不需要创建新的向量。

默认情况下,当向量需要增加其内部数据结构的大小以容纳更多元素时,内部数据结构的大小加倍,而对于ArrayList,大小仅增加50%。所以ArrayList在空间方面更加保守。

LinkedList 更灵活,允许您从集合的两边插入,添加和删除元素 - 它可以用作队列甚至是双端队列!在内部,LinkedList不使用数组。 LinkedList是一系列节点,它们是双链接的。每个节点包含标题,实际存储对象,以及指向下一个或上一个节点的两个链接或指针。 LinkedList看起来像一个链,由持有对方的人组成。您可以将人员或节点插入该链或删除。链接列表允许在常量时间内在列表中的任何位置插入/删除节点。

因此,在链表中插入元素(无论是在头部还是在尾部或中间)并不昂贵。此外,当您从头部检索元素时,它很便宜。但是,当您想要随机访问链表的元素或访问列表尾部的元素时,操作很繁重。因为,要访问第n + 1个元素,您需要解析前n个元素以到达第n + 1个元素。

链接列表也不同步。因此,需要在外部同步修改和读取列表的多个线程。

因此,选择用于创建列表的类取决于要求。当您需要在列表末尾添加元素并随机访问元素时,可以使用ArrayList或Vector(如果需要同步) - 比添加操作更多的访问操作。而当您需要从列表的头部或中间执行大量添加/删除(元素)操作时,应使用LinkedList,而您的访问操作相对较少。