【问题标题】:Best way to remove repeats in a collection in Java?在Java中删除集合中重复的最佳方法?
【发布时间】:2009-06-29 20:01:12
【问题描述】:

这是一个由两部分组成的问题:

首先,我很想知道从集合中删除重复元素的最佳方法是什么。到目前为止,我一直在做的方式是将集合简单地转换为集合。我知道集合不能有重复的元素,所以它只是为我处理它。

这是一个有效的解决方案吗?循环和删除重复会更好/更惯用/更快吗?有关系吗?

我的第二个(相关)问题是:将数组转换为 Set 的最佳方法是什么?假设一个数组 arr 我一直这样做的方式如下:

Set x = new HashSet(Arrays.asList(arr));

这会将数组转换为列表,然后转换为集合。好像有点绕道有没有比双重转换方式更好/更惯用/更有效的方式来做到这一点?

谢谢!

【问题讨论】:

  • 好问题,您可能希望将它们分成两个单独的 SO 问题。

标签: java arrays set


【解决方案1】:
  1. 您是否有关于该集合的任何信息,例如说它已经排序,或者它包含大部分重复项或大部分唯一项?只需一个任意集合,我认为将其转换为 Set 就可以了。

  2. Arrays.asList() 不会创建全新的列表。它实际上只返回一个List,它使用数组作为其后备存储,所以这是一个便宜的操作。所以你从数组中创建Set 的方式也是我的做法。

【讨论】:

    【解决方案2】:

    使用HashSet 的标准Collection conversion constructor。根据The Java Tutorials

    这是一个简单但有用的 Set 习语。 假设您有一个 Collection,c 和 你想创建另一个集合 包含相同的元素但具有 消除所有重复。这 跟随单线就可以了。

    Collection<Type> noDups = new HashSet<Type>(c);
    

    它通过创建一个 Set 来工作(通过 定义,不能包含 重复),最初包含所有 c中的元素。它使用 标准转换构造函数 在The Collection Interface 部分中描述。

    这里是这个成语的一个小变体 保留的顺序 删除时的原始集合 重复元素。

    Collection<Type> noDups = new LinkedHashSet<Type>(c);
    

    以下是一个通用方法 封装了前面的成语, 返回一组相同的泛型 输入作为传递的那个。

    public static <E> Set<E> removeDups(Collection<E> c) {
        return new LinkedHashSet<E>(c);
    }
    

    【讨论】:

      【解决方案3】:

      假设您真的想要设置语义,从包含重复的集合中创建一个新的Set 是一个很好的方法。它的意图是什么非常清楚,它比自己做循环更紧凑,并且它使源集合完好无损。

      对于从数组创建Set,创建中间List 是一种常用方法。 Arrays.asList() 返回的包装器是轻量级和高效的。不幸的是,核心 Java 中没有更直接的 API 可以做到这一点。

      【讨论】:

        【解决方案4】:

        我认为您将项目放入集合以生成独特项目集合的方法是最好的方法。清晰、高效、正确。

        如果您在进入集合的过程中使用 Arrays.asList() 感到不舒服,您可以简单地在数组上运行一个 foreach 循环以将项目添加到集合中,但我看不出有任何危害(对于非原始数组)在您的方法中。 Arrays.asList() 返回一个由源数组“支持”的列表,因此它在时间或空间上没有显着的成本。

        【讨论】:

          【解决方案5】:

          1。 重复

          同意其他答案:使用Set 应该是删除重复项的最有效方法。 HashSet 平均应该在 O(n) 时间内运行。循环和删除重复将按照O(n^2) 的顺序运行。所以在大多数情况下建议使用Set。在某些情况下(例如内存有限),迭代可能有意义。

          2。 Arrays.asList() 是一种不复制数组的廉价操作,内存开销最小。您可以通过遍历数组来手动添加元素。

          
          public static  Set arrayToSet(T[] array) {
            Set set = new HashSet(array.length / 2);
            for (T item : array)
              set.add(item);
            return set;
          }
          

          【讨论】:

            【解决方案6】:

            除非您知道任何特定的性能瓶颈(例如数万个项目的集合),否则转换为集合是一个完全合理的解决方案,应该是(IMO)您解决此问题的第一种方法,并且只寻找如果有特定的问题需要解决,那就更棒了。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-03-13
              • 2010-09-17
              • 1970-01-01
              • 2017-11-07
              • 1970-01-01
              • 2015-11-02
              • 2013-05-03
              • 2016-02-11
              相关资源
              最近更新 更多