2009-06-29 69 views
0

这是一个由两部分组成的问题:在Java中删除集合中重复的最佳方法?

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

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

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

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

该数组到一个列表转换,然后进入一组。似乎有点迂回。有没有比双重转换方式更好/更习惯/更有效的方式来做到这一点?

谢谢!

+1

好的问题,你可能想把它们分成两个单独的SO问题。 – 2009-06-29 20:07:11

回答

7
  1. 您是否有任何关于集合的信息,比如说它已经排序,或者它包含大部分重复或大部分独特的项目?随着任意集合,我认为将其转换为Set是好的。

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

2

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

对于从数组创建Set,创建中间List是一种常见方法。由Arrays.asList()返回的包装重量轻,效率高。不幸的是,在核心Java中没有更直接的API来执行此操作。

4

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

这里有一个简单但有用的Set成语。 假设你有一个Collection,c和 你想创建另一个Collection 包含相同的元素,但是 所有重复项都被删除了。一行之后的 就是这样做的。

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

它通过创建一组(其中, 定义,不能包含 式两份),最初包含在c中所有 的元素。它使用The Collection Interface部分中描述的 标准转换构造函数 。

下面是这个成语 ,可以保留原 收集的顺序,同时消除 重复元素的一个小的变体。

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

以下是 封装前述成语, 返回相同的通用类型 作为一个传递的Set的通用方法。

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

我觉得你把物品放入一组以产生独特的项目收集的方式是最好的之一。它清晰,高效,正确。

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

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

除非你知道的(说的项目数以万计的集合)转换为一组是一个完全合理的解决方案,应该是(IMO)你解决这个问题的第一种方式的任何特定的性能瓶颈,只有在有特定问题需要解决时才寻找更有价值的东西。

相关问题