【问题标题】:What's faster, creating a Set or removing from a List?什么更快,创建一个集合或从列表中删除?
【发布时间】:2014-04-04 20:41:16
【问题描述】:

我已经有一个List<T>,它可能包含也可能不包含重复项。我将根据使用它们的一些计算结果构建一个Set<String>,因为在某些情况下,两个不同的Ts 可以产生相同的String

List<T> 中的一些元素有不受欢迎的属性,所以我需要将它们过滤掉。我这样过滤:

List<T> myList = myCoolListGetter();
Iterator<T> it = myList.iterator();
T curr;
while (it.hasNext()) {
    curr = it.next();
    if (curr.shouldNotBeInResult()) {
        myList.remove(curr);
    }
}

然后我将这个List&lt;T&gt; 传递给另一个方法,该方法执行我提到的那些计算,将它们添加到Set&lt;String&gt;

我想也许我可以通过将应该在结果中的元素插入Set&lt;T&gt; 而不是从List&lt;T&gt; 中删除它们来节省一些时间。由于我已经在这里迭代了List&lt;T&gt;,并且无论如何都必须稍后构造一个Set&lt;String&gt;,所以我真的可以通过这样做来节省时间吗?

【问题讨论】:

  • 我会说使用前一种方法,因为它更干净并且可以按预期执行。除了您应该使用it.remove 而不是myList.remove(curr) 以更快地删除。
  • 您可以使用System.currentTimeMillis()获取开始时间,然后创建Set并再次调用System.currentTimeMillis()获取结束时间。结束时间减去开始时间,得到经过的时间。重复 List 删除方法并比较结果。
  • @MikeB 将进行微基准测试。在尝试进行此类测试之前,请参阅How do I write a correct micro-benchmark in Java?
  • 在问“什么更快?”之前,你应该先问,“这有关系吗?”
  • @LieRyan 有时会,这取决于您正在使用的系统类型。我正在开发的当前系统是基于这种方法制作的就是提升所有系统的性能...

标签: java list set


【解决方案1】:

IMO,创建一个新的List&lt;T&gt; 会比从现有的List&lt;T&gt; 中删除更好,如果您可以指定足够的初始容量(请参阅 - public ArrayList(int initialCapacity),让您指定的构造函数ArrayList 在构建时的容量)。因为那样你只会向它添加元素,而不必重新调整容量。重新调整意味着创建一个新的支持数组并将现有元素复制到该新数组。

另一方面,从列表中删除需要将其余元素向左移动。此操作不需要移动元素的唯一情况是要删除的元素是最后一个元素。

我之所以说 - 一个新的 List&lt;T&gt; 而不是 Set&lt;T&gt; 是因为与集合不同,列表不需要关心添加的元素是否重复。

【讨论】:

    【解决方案2】:

    考虑使用 Google Guava 的 filterPredicate

    Collection<T> filtered = Collections2.filter(myCoolListGetter(),
        new Predicate<T>() {
          public boolean apply(T t) {
            return !t.shouldNotBeInResult();
          }
        });
    

    Iterable <T> filtered = Iterables.filter(myCoolListGetter(),
        new Predicate<T>() {
          public boolean apply(T t) {
            return !t.shouldNotBeInResult();
          }
        });
    

    返回的集合/迭代器将被延迟评估,如果迭代则 O(n)。懒惰的评价很方便。 Iterables.filter 特别好,因为它只呈现原始 Iterable(列表)的过滤视图。没有创建新的ArrayList,它只是遍历每个项目并调用apply

    【讨论】:

      【解决方案3】:

      大概吧。在 HashSet 中插入一些东西是 O(1),因为散列使得重复检查非常快。所以添加 n 个东西只会是 O(n),这就是遍历你的列表需要多长时间。

      【讨论】:

      • 可能……什么?创建Set 可能比从List 中删除更快?
      猜你喜欢
      • 2015-12-05
      • 1970-01-01
      • 2021-10-05
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      • 2020-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多