Подтвердить что ты не робот

Удалить дубликаты из списка с помощью Guava

Как удалить дубликаты из списка с помощью Guava api?

В настоящее время я следую этому:

private List<T> removeDuplicate(List<T> list){
return new ArrayList<T>(new LinkedHashSet<T>(list));
}
4b9b3361

Ответ 1

Вероятно, наиболее эффективным способом является ImmutableSet.copyOf(list).asList(), который устраняет дубликаты и сохраняет порядок итерации.

(Но ваша реализация с LinkedHashSet была бы почти такой же эффективной и не могла бы запускать нули, в маловероятном случае вам действительно нужны нули в вашей коллекции.)

Ответ 2

Я люблю ответ Луи за его простоту (и потому что это единственный ответ, который не требует 2 полных итераций), но, к сожалению, в реальном мире, вы часто сталкиваетесь с ситуациями, когда null происходит. Здесь немного более длинная версия с нулевой безопасностью:

ImmutableSet.copyOf(
    Iterables.filter(
        list, Predicates.not(Predicates.isNull()))).asList();

Или со статическим импортом:

copyOf(filter(list, not(isNull()))).asList();

Конечно, вам нужно знать, что все значения null будут потеряны из списка.

Ответ 3

с общим предикатом

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

}

Ответ 4

Если вы хотите использовать Guava любой ценой, вы можете сделать

return new ArrayList<T>(HashMultiSet<T>.create(list).elementSet())

Ответ 5

Я действительно не рекомендую использовать (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() возвращает представление.

Ответ 6

Вы можете попробовать Guava MultiSet API для удаления дубликатов. Просто добавьте свой список в набор и используйте метод count.

MultiSet