这是一个由两部分组成的问题:
首先,我很想知道从集合中删除重复元素的最佳方法是什么。到目前为止我一直在做的方法是简单地将集合转换为集合。我知道套装不能有重复元素所以它只是为我处理它。
这是一种有效的解决方案吗?循环和删除重复会更好/更惯用/更快吗?这有关系吗?
我的第二个(相关)问题是:将数组转换为Set的最佳方法是什么?假设一个数组arr我一直这样做的方法如下:
Set x = new HashSet(Arrays.asList(arr));
这会将数组转换为列表,然后转换为集合。似乎有点迂回。是否有比双转换方式更好/更惯用/更有效的方法?
谢谢!
答案 0 :(得分:7)
您是否有关于该集合的任何信息,例如它已经排序,或者它主要包含重复项或大多数独特项目?只需一个任意的集合,我认为将其转换为Set
就可以了。
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)解决此问题的第一种方式,并且只能查找如果有特定问题需要解决,那就更有趣了。