我们正在使用一种软件来维护代码质量,今天我从中发现一个发现,说在数组列表上调用contains()
效率很低。建议的方法(可能更好)是使用 HashSets 。
关于该软件,这:
boolean doesContain = (new HashSet<>(arrayList)).contains("something");
比这更有效:
boolean doesContain = arrayList.contains("something");
这真的可以吗?如果是,为什么?
答案 0 :(得分:2)
new HashSet<>(arrayList)
花费 O(n)时间和 O(n)空间来构建HashSet
。
hashSet.contains("something")
花费 O(1)时间来查找元素。
arrayList.contains("something")
花费 O(n)时间来查找元素。
结果:
(new HashSet<>(arrayList)).contains("something")
占用 O(n)+ O(1)= O(n)时间+ O(n)空间复杂度
arrayList.contains("something")
花费 O(n)时间+ 0空间复杂度
这意味着根据 Big O 表示法,这两个表达式都具有 O(n)时间的复杂度,但是arrayList.contains("something")
不会占用额外的空间,而是新创建的HashSet
。
P.S。
由于我不了解您的应用程序的其他相关方面,因此我无法对其他情况做出任何预测。我只分析给定的一段代码。
答案 1 :(得分:0)
可能。要检查元素是否在列表中,我们必须按顺序检查每个元素。
元素0是我们正在寻找的元素吗?是/否
元素1是我们要寻找的元素吗?是/否
...
等。
很明显,您可以停止迭代。
复杂度:
HashSet始终是恒定时间查找。您只需计算哈希码并调用Object::equals
。
关于您是否应该使用一套,这实际上取决于您使用它的目的。如果仅执行contains
,则最合适的方法是设置集合。否则,请参见Which Java Collection should I use?