Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как удалить дубликаты из списка

Короткий ответ

distinct() в потоке оставляет первое вхождение каждого значения и сохраняет порядок:

void main() {
    var numbers = List.of(3, 1, 3, 2, 1);
    IO.println(numbers.stream().distinct().toList());
}

Результат:

[3, 1, 2]

Через множество

Множество хранит только уникальные значения. LinkedHashSet при этом помнит порядок добавления:

void main() {
    var tags = List.of("java", "sql", "java", "git");
    var unique = new ArrayList<>(new LinkedHashSet<>(tags));
 
    IO.println(unique);
}

Результат:

[java, sql, git]

Уникальность по полю

Чтобы оставить по одному объекту для каждого значения поля, соберите их в Map по этому полю:

record User(String email, String name) {}
 
void main() {
    var users = List.of(
            new User("anna@site.com", "Anna"),
            new User("oleg@site.com", "Oleg"),
            new User("anna@site.com", "Anna Smith"));
 
    var unique = users.stream()
            .collect(Collectors.toMap(User::email, u -> u, (first, second) -> first, LinkedHashMap::new))
            .values();
    IO.println(unique);
}

Результат:

[User[email=anna@site.com, name=Anna], User[email=oleg@site.com, name=Oleg]]

Без учёта регистра

TreeSet с компаратором без учёта регистра считает Java и java одинаковыми:

void main() {
    var set = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
    set.addAll(List.of("Java", "java", "SQL", "sql", "Git"));
 
    IO.println(set);
}

Результат:

[Git, Java, SQL]

Частая ошибка

Использовать HashSet, если важен порядок. Он не сохраняет порядок добавления:

void main() {
    var words = List.of("pear", "apple", "kiwi", "pear", "banana");
    IO.println(new HashSet<>(words));
}

Результат:

[banana, apple, pear, kiwi]

Порядок HashSet зависит от хеш-кодов и может отличаться от исходного. Если порядок важен, берите LinkedHashSet или distinct().

Функции из этого ответа

  • Stream.distinct() — Убирает повторяющиеся элементы потока.
  • LinkedHashSet — Множество, которое помнит порядок добавления элементов.
  • HashSet — Множество без повторов на основе хеш-таблицы; порядок не гарантирован.
  • Collectors.toMap() — Сборщик, который строит словарь из элементов потока.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.