在arraylist上调用contains()效率低下吗?

时间:2018-11-27 10:16:07

标签: java arraylist hashset

我们正在使用一种软件来维护代码质量,今天我从中发现一个发现,说在数组列表上调用contains()效率很低。建议的方法(可能更好)是使用 HashSets

关于该软件,这:

boolean doesContain = (new HashSet<>(arrayList)).contains("something");

比这更有效:

boolean doesContain = arrayList.contains("something");

这真的可以吗?如果是,为什么?

2 个答案:

答案 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是我们要寻找的元素吗?是/否
...
等。

很明显,您可以停止迭代。

复杂度:

  • 最佳情况:这是第一个元素。这是一个恒定的时间查找。 O(1)
  • 平均情况:在中间。 O(n / 2)
  • 最坏情况: 这是最后一个元素。我们必须对每个元素进行比较。 O(n)

HashSet始终是恒定时间查找。您只需计算哈希码并调用Object::equals

关于您是否应该使用一套,这实际上取决于您使用它的目的。如果仅执行contains,则最合适的方法是设置集合。否则,请参见Which Java Collection should I use?