如何在 Guava api 的帮助下从List中删除重复项?
目前我正在关注此事:
private List<T> removeDuplicate(List<T> list){
return new ArrayList<T>(new LinkedHashSet<T>(list));
}
答案 0 :(得分:68)
最有效的方法可能是ImmutableSet.copyOf(list).asList()
,它可以消除重复并保留迭代顺序。
(但是你使用LinkedHashSet
的实现几乎同样有效,并且不会抛出空值,万一你真的想要集合中的空值。)
答案 1 :(得分:12)
我喜欢Louis' answer以简化它(并且因为它是唯一不需要2次完整迭代的答案),但遗憾的是在现实世界中,您经常遇到null
所做的情况发生。这是一个稍微长一点的零安全版本:
ImmutableSet.copyOf(
Iterables.filter(
list, Predicates.not(Predicates.isNull()))).asList();
或者,使用静态导入:
copyOf(filter(list, not(isNull()))).asList();
当然,您需要了解所有null
值都会从列表中丢失。
答案 2 :(得分:7)
使用通用谓词
class DuplicateRemover<T> implements Predicate<T> {
private final Set<T> set = new HashSet<>();
@Override
public boolean apply(T input) {
boolean flag = set.contains(input);
if (!flag) {
set.add(input);
}
return !flag;
}
}
答案 3 :(得分:1)
如果你想以任何价格使用番石榴,你可以做到
return new ArrayList<T>(HashMultiSet<T>.create(list).elementSet())
答案 4 :(得分:1)
我真的不建议使用(Linked)HashMultiSet
执行通常使用上面提到的OP ArrayList
和(Linked)HashSet
执行的任务 - 它对常规Java程序员和(可能)的可读性较差效率低下。
相反,至少使用静态工厂构造函数(如newArrayList
和newLinkedHashSet
)来避免所有这些<T>
:
private static <T> List<T> removeDuplicate(final List<T> list) {
return Lists.newArrayList(Sets.newLinkedHashSet(list));
}
但是,你可以用更多“番石榴方式” - avoiding nulls并使用immutable collections来完成。
因此,如果您的收藏不能包含空元素,我建议您使用immutable set代替mutable and less efficient one:
private static <T> List<T> removeDuplicate(final List<T> list) {
return Lists.newArrayList(ImmutableSet.copyOf(list));
}
它仍在复制对象两次,因此请考虑完全不可变并更改方法签名以返回ImmutableList
:
private static <T> ImmutableList<T> removeDuplicate(final List<T> list) {
return ImmutableSet.copyOf(list).asList();
}
这种方式只涉及一次复制,因为ImmutableCollection.asList()
会返回一个视图。
答案 5 :(得分:0)
您可以尝试使用Guava的MultiSet API删除重复项。只需添加您的列表,然后使用count方法。