在Java中删除集合中重复的最佳方法?

时间:2009-06-29 20:01:12

标签: java arrays set

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

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

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

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

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

这会将数组转换为列表,然后转换为集合。似乎有点迂回。是否有比双转换方式更好/更惯用/更有效的方法?

谢谢!

6 个答案:

答案 0 :(得分:7)

  1. 您是否有关于该集合的任何信息,例如它已经排序,或者它主要包含重复项或大多数独特项目?只需一个任意的集合,我认为将其转换为Set就可以了。

  2. Arrays.asList()未创建全新的列表。它实际上只返回一个List,它使用数组作为它的后备存储,因此它是一个廉价的操作。所以你从阵列中制作Set的方式也就是我的做法。

答案 1 :(得分:4)

使用HashSet的标准Collection conversion constructor。根据{{​​3}}:

  

这是一个简单但有用的Set惯用语。   假设你有一个Collection,c和   你想创建另一个集合   含有相同的元素,但含有   所有重复的消除。该   以下单行就可以了。

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

它的工作原理是创建一个Set(by,by   定义,不能包含   重复),最初包含所有   c中的元素。它使用了   标准转换构造函数   在The Java Tutorials部分中描述。

     

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

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

以下是一般的方法   封装了前面的习语,   返回一组相同的泛型   输入的类型。

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

答案 2 :(得分:2)

假设您确实需要设置语义,从包含副本的集合创建新的Set是一种很好的方法。非常清楚意图是什么,它比自己做循环更紧凑,并且它保留了源集合。

要从数组创建Set,创建中间List是一种常见方法。 Arrays.asList()返回的包装器轻巧而高效。不幸的是,核心Java中没有更直接的API来做到这一点。

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

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;
}

答案 5 :(得分:1)

除非您知道的任何特定性能瓶颈(比如成千上万个项目的集合)转换为一个集合是一个非常合理的解决方案,并且应该是(IMO)解决此问题的第一种方式,并且只能查找如果有特定问题需要解决,那就更有趣了。