Как удалить дубликаты из списка с помощью Guava api?
В настоящее время я следую этому:
private List<T> removeDuplicate(List<T> list){
return new ArrayList<T>(new LinkedHashSet<T>(list));
}
Как удалить дубликаты из списка с помощью Guava api?
В настоящее время я следую этому:
private List<T> removeDuplicate(List<T> list){
return new ArrayList<T>(new LinkedHashSet<T>(list));
}
Вероятно, наиболее эффективным способом является ImmutableSet.copyOf(list).asList()
, который устраняет дубликаты и сохраняет порядок итерации.
(Но ваша реализация с LinkedHashSet
была бы почти такой же эффективной и не могла бы запускать нули, в маловероятном случае вам действительно нужны нули в вашей коллекции.)
Я люблю ответ Луи за его простоту (и потому что это единственный ответ, который не требует 2 полных итераций), но, к сожалению, в реальном мире, вы часто сталкиваетесь с ситуациями, когда null
происходит. Здесь немного более длинная версия с нулевой безопасностью:
ImmutableSet.copyOf(
Iterables.filter(
list, Predicates.not(Predicates.isNull()))).asList();
Или со статическим импортом:
copyOf(filter(list, not(isNull()))).asList();
Конечно, вам нужно знать, что все значения null
будут потеряны из списка.
с общим предикатом
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;
}
}
Если вы хотите использовать Guava любой ценой, вы можете сделать
return new ArrayList<T>(HashMultiSet<T>.create(list).elementSet())
Я действительно не рекомендую использовать (Linked)HashMultiSet
для выполнения задачи, которая обычно выполняется с помощью ArrayList
и (Linked)HashSet
, таких как OP, упомянутых выше - она менее читаема для обычного Java-программиста и (возможно) менее эффективной.
Вместо этого, по крайней мере, используйте статические конструкторы factory, такие как newArrayList
и newLinkedHashSet
, чтобы избежать всех этих <T>
s:
private static <T> List<T> removeDuplicate(final List<T> list) {
return Lists.newArrayList(Sets.newLinkedHashSet(list));
}
Однако вы можете сделать это более "Путь Guava" - избегая нулей и используя неизменные коллекции.
Итак, если ваша коллекция не может иметь нулевые элементы, я бы предложил использовать неизменяемый набор вместо изменчивый и менее эффективный:
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()
возвращает представление.
Вы можете попробовать Guava MultiSet API для удаления дубликатов. Просто добавьте свой список в набор и используйте метод count.