Java Set.contains(o)与List.get(index)时间复杂度

时间:2015-08-21 17:04:10

标签: java performance list set time-complexity

我正在创建一个股票应用程序,在这里我保存了购买特定股票时的指数历史。目前我使用HashSet<Integer>来保存这些值(范围0-270)。

在该计划中,对此历史记录进行了大量使用Set.contains(o)的查询,即O(1)

我考虑将此历史记录更改为ArrayList<Boolean>,其中索引为0的true表示索引0处有买入,索引1处的false表示存在不买指数等等......

这样,我可以List.get(index)O(1)也是HashSet,但由于awk -F: '{ list[$1] = list[$1] $2 } END { for (i in list) printf "%s:%s\n", i, list[i] }' 查找的基本特性,我猜测会稍快一些。

但由于指数的范围很小,我不确定我的假设是否成立。

所以,如果我不关心空间复杂性,哪种方法会更快?

3 个答案:

答案 0 :(得分:6)

由于您的范围很小,最快是直接使用数组:

boolean[] values = new boolean[271];

// get the value (equivalent to your hashset.contains(index)):
boolean contained = values[index];

它不涉及hashCode所需的任何equals / HashSet次操作。这大致相当于使用ArrayList<Boolean>减去(非常小的)调用堆栈。

数组查找绝对是O(1) 非常快 操作。

您还可以考虑使用yshavit建议的BitSet

答案 1 :(得分:4)

除了上面提到的boolean[],您还可以考虑使用BitSet。它的设计几乎完全符合这些目的。

BitSet bs = new BitSet(271);
bs.set(someIndex);
boolean isSet = bs.get(anotherIndex);

这比boolean[]更紧凑,占用34个字节而不是270个字节(不计算标题,大致相当)。它还可以更灵活地处理边界 - 如果您尝试在270以上的索引处设置一个位,它将起作用而不是抛出异常。这是好事还是坏事取决于你。

答案 2 :(得分:0)

很明显,数组[index]比[set / list] .get(index)更快,否则现代JIT会以某种方式对其进行优化,使你无法看到差异,除非您的应用具有非常高的关键性能要求。