我一直很喜欢树,O(n*log(n))和它们的整洁。然而,我所认识的每个软件工程师都尖锐地问过我为什么要使用TreeSet。从CS的背景来看,我不认为你使用什么很重要,我也不关心在哈希函数和桶(在Java的情况下)上搞得一团糟。
在哪些情况下,我应该在树集上使用HashSet ?
我一直很喜欢树,O(n*log(n))和它们的整洁。然而,我所认识的每个软件工程师都尖锐地问过我为什么要使用TreeSet。从CS的背景来看,我不认为你使用什么很重要,我也不关心在哈希函数和桶(在Java的情况下)上搞得一团糟。
在哪些情况下,我应该在树集上使用HashSet ?
当前回答
HashSet是O(1)来访问元素,所以这当然很重要。但是保持集合中对象的顺序是不可能的。
如果维护顺序(根据值而不是插入顺序)对您很重要,TreeSet是有用的。但是,正如您所注意到的,您正在以顺序换取访问元素的更慢时间:基本操作为O(log n)。
来自TreeSet的javadocs:
该实现为基本操作(添加、删除和包含)提供了log(n)的时间成本。
其他回答
HashSet是O(1)来访问元素,所以这当然很重要。但是保持集合中对象的顺序是不可能的。
如果维护顺序(根据值而不是插入顺序)对您很重要,TreeSet是有用的。但是,正如您所注意到的,您正在以顺序换取访问元素的更慢时间:基本操作为O(log n)。
来自TreeSet的javadocs:
该实现为基本操作(添加、删除和包含)提供了log(n)的时间成本。
消息编辑(完全重写)当顺序无关紧要时,就是这样。两者都应该给出Log(n) -看看其中一个是否比另一个快5%以上是有用的。HashSet可以在循环中给出O(1)测试,应该可以揭示它是否正确。
明明可以吃橘子,为什么要吃苹果?
Seriously guys and gals - if your collection is large, read and written to gazillions of times, and you're paying for CPU cycles, then the choice of the collection is relevant ONLY if you NEED it to perform better. However, in most cases, this doesn't really matter - a few milliseconds here and there go unnoticed in human terms. If it really mattered that much, why aren't you writing code in assembler or C? [cue another discussion]. So the point is if you're happy using whatever collection you chose, and it solves your problem [even if it's not specifically the best type of collection for the task] knock yourself out. The software is malleable. Optimise your code where necessary. Uncle Bob says Premature Optimisation is the root of all evil. Uncle Bob says so
如果您没有插入足够多的元素导致频繁重散列(或冲突,如果您的HashSet不能调整大小),那么HashSet当然可以为您提供常量时间访问的好处。但是对于有大量增长或收缩的集合,使用Treesets实际上可能会获得更好的性能,这取决于实现。
如果我没记错的话,平摊时间可以接近于一个功能性红黑树的O(1)。冈崎的书会有比我更好的解释。(或参阅他的出版物列表)
1.HashSet允许空对象。
2.树集不允许空对象。如果你试图添加空值,它将抛出一个NullPointerException。
3.HashSet比TreeSet快得多。
e.g.
TreeSet<String> ts = new TreeSet<String>();
ts.add(null); // throws NullPointerException
HashSet<String> hs = new HashSet<String>();
hs.add(null); // runs fine