Java Collections Framework实现的Big-O摘要?[关闭]


164

我可能很快就会教“ Java速成课程”。尽管可以很安全地假定听众成员将知道Big-O表示法,但是假设他们将知道各种集合实现上的各种操作的顺序可能是不安全的。

我可能会花一些时间自己生成一个摘要矩阵,但是如果它已经存在于公共领域中的某个地方,我肯定会重用它(当然要有适当的信誉)。

有人有指针吗?


在讨论一些非常常见的Java对象以及使用Big-O表示法操作它们的成本时,我发现这是一个有用的链接。objectissues.blogspot.com/2006/11/…–
尼克,

尽管不是公共领域,但是Maurice Naftalin和Philip Wadler撰写的出色的Java Generics和Collections在其有关不同集合类的章节中列出了运行时信息概述。
Fabian Steeg

1
性能基准会有用吗?
ThreaT 2015年

Answers:


149

该网站相当不错,但并不特定于Java:http//bigocheatsheet.com/ 这是一张图片,以防此链接不起作用


27
这就是为什么我们不使用URL作为答案的原因。据我所知,该文档/服务器不再可用!
詹森·莫克

1
@Ben J链接不再有效
Vikas V

Web存档链接现在也已断开。
MikeFHay

似乎添加了新的工作URL。感谢您的努力,这非常有帮助。
Tejas C

1
@AndreaZilio LinkedList.remove(Object)是恒定时间,假设您已经知道邻居。如果您不认识邻居,则是首先找到它的线性时间。
Paul Evans

217

Java Generics and Collections》一书中包含此信息(页面:188、211、222、240)。

列出实现:

                      get  add  contains next remove(0) iterator.remove
ArrayList             O(1) O(1) O(n)     O(1) O(n)      O(n)
LinkedList            O(n) O(1) O(n)     O(1) O(1)      O(1)
CopyOnWrite-ArrayList O(1) O(n) O(n)     O(1) O(n)      O(n)

设置实现:

                      add      contains next     notes
HashSet               O(1)     O(1)     O(h/n)   h is the table capacity
LinkedHashSet         O(1)     O(1)     O(1) 
CopyOnWriteArraySet   O(n)     O(n)     O(1) 
EnumSet               O(1)     O(1)     O(1) 
TreeSet               O(log n) O(log n) O(log n)
ConcurrentSkipListSet O(log n) O(log n) O(1)

地图实现:

                      get      containsKey next     Notes
HashMap               O(1)     O(1)        O(h/n)   h is the table capacity
LinkedHashMap         O(1)     O(1)        O(1) 
IdentityHashMap       O(1)     O(1)        O(h/n)   h is the table capacity 
EnumMap               O(1)     O(1)        O(1) 
TreeMap               O(log n) O(log n)    O(log n) 
ConcurrentHashMap     O(1)     O(1)        O(h/n)   h is the table capacity 
ConcurrentSkipListMap O(log n) O(log n)    O(1)

队列实现:

                      offer    peek poll     size
PriorityQueue         O(log n) O(1) O(log n) O(1)
ConcurrentLinkedQueue O(1)     O(1) O(1)     O(n)
ArrayBlockingQueue    O(1)     O(1) O(1)     O(1)
LinkedBlockingQueue   O(1)     O(1) O(1)     O(1)
PriorityBlockingQueue O(log n) O(1) O(log n) O(1)
DelayQueue            O(log n) O(1) O(log n) O(1)
LinkedList            O(1)     O(1) O(1)     O(1)
ArrayDeque            O(1)     O(1) O(1)     O(1)
LinkedBlockingDeque   O(1)     O(1) O(1)     O(1)

java.util包的javadoc底部包含一些良好的链接:


3
您必须指定哪种情况是这些数字,例如,如果删除数组中间或结尾的元素,则从Arraylist中删除可能需要O(n)。
Popeye

@popeye通常不是最坏的情况吗?
Yassin Hajaj

正如@Popeye所提到的,应该对答案的具体情况有一个清晰的描述。对于时间复杂度,情况可能是平均/最坏。答案似乎是指所有DS的“平均”情况。
Yashwin Munsadwala

12

Sun的每个集合类的Javadocs通常都会告诉您您想要什么。HashMap,例如:

假设哈希函数将元素正确分散在存储桶中,则此实现为基本操作(获取和放置)提供恒定时间的性能。集合视图上的迭代所需的时间与HashMap实例的“容量”(存储桶数)及其大小(键-值映射数)成正比

TreeMap

此实现为containsKey,get,put和remove操作提供了保证的log(n)时间成本

TreeSet

此实现为基本操作(添加,删除和包含)提供了保证的log(n)时间成本

(强调我的)


我不同意HashMap部分。我知道Sun的位置,但是...例如必须调用obj.equals(key),该对象的大小可能是线性的。考虑到您通常必须阅读此比较的字段。例外是整数或字符串(内部)????
溢出

首先,如果他们错了,那么创建一个证明恒定时间性能的测试用例对您来说应该不太难吗?其次,如果您查看HashMap的源代码,它不会针对映射中的每个键调用equals()-仅当哈希码相等时才调用equals()。
马特b

5
如果您阅读上面的引文,它表示是固定时间的“假设哈希函数将元素正确地分散在存储桶中”。根据CS理论,当哈希函数为“好”(平均发生)时,哈希表具有恒定的时间操作,但在最坏的情况下可能会花费线性时间。
newacct

4
@Overflown-从技术角度来讲,从复杂性角度来看obj.equals()花费多长时间都没有关系,因为这只是与集合中项目数有关的“常量”的一部分。
mikera 2010年

6

上面的家伙比较了HashMap / HashSet与TreeMap / TreeSet。

我将谈论ArrayList与LinkedList:

数组列表:

  • O(1) get()
  • 摊销O(1) add()
  • 如果您使用ListIterator.add()或在中间插入或删除元素Iterator.remove(),则将以下所有元素移位为O(n)

链表:

  • 上) get()
  • O(1) add()
  • 如果使用ListIterator.add()或在中间插入或删除元素,则该元素Iterator.remove()将为O(1)

1
if you insert or delete an element in the middle using ListIterator.add() or Iterator.remove(), it will be O(1) 为什么?首先,我们需要在中间找到元素,那么为什么不选择O(n)?
MyTitle

@MyTitle:再次阅读。“使用” ListIterator.add()Iterator.remove()“我们有一个迭代器。
newacct
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.