Как удалить уникальные значения из списка List

Рейтинг: -1Ответов: 2Опубликовано: 05.04.2023

Имеется List со значениями, например [111, 222, 333, 444, 111, 333] Нужно удалить уникальные значения, то есть [222, 444] Что бы в списке осталось:[111, 333, 111, 333], то есть оставить каждый дубль на месте, удалив неповторяющиеся элементы. Написал код, для поиска дубликатов, но он выводит из только по одному разу:

public class Main {
    public static void main(String[] args) {
        List<String> ids = new ArrayList<>(Arrays.asList("111", "222", "333", "111", "333"));
        List<String> idsD = new ArrayList<>();
        for (int i = 0; i < ids.size() - 1; i++) {
            for (int j = i + 1; j < ids.size(); j++) {
                if (ids.get(i).equals(ids.get(j))) {
                    idsD.add(ids.get(i));
                }
            }
        }
        System.out.println(ids);
        System.out.println(idsD);
    }
}

вывод:

[111, 333]

Как можно сделать? (без стримов и лямбд, т.к. java5)

Ответы

▲ 1Принят

Заводите HashMap, в котором ключи - ваши значения из исходного списка, значения - количество повторений. Первым циклом считаете, сколько раз каждое значение встречается, вторым во второй список добавляете значения, которые встретились более одного раза:

public static void main(String[] args) {
    List<String> source = Arrays.asList("111", "222", "333", "111", "333");
    List<String> result = new ArrayList<>();
    Map<String, Integer> counter = new HashMap<>();

    for (int i = 0; i < source.size(); i++) {
        String key = source.get(i);
        counter.put(key, counter.getOrDefault(key, 0) + 1);
    }

    for (int i = 0; i < source.size(); i++) {
        String key = source.get(i);
        if (counter.get(key) > 1) {
            result.add(key);
        }
    }

    System.out.println(source);
    System.out.println(result);
}
▲ 1

Подобного рода вопросы задаются достаточно часто в разных формулировках, например:

Решение с использованием двух сетов (в стиле Java 5 без "алмазного" оператора <>) может выглядеть так:

  • Модификация исходного списка с использованием List::retainAll
public static <T> void removeUniques(List<T> list) {
    Set<T> ones = new HashSet<T>();
    Set<T> dups = new HashSet<T>();
    for (T t : list) {
        if (!ones.add(t)) {
            dups.add(t);
        }
    }
    list.retainAll(dups);
}
  • Создание нового списка
public static <T> List<T> getDuplicates(List<T> list) {
    Set<T> ones = new HashSet<T>();
    Set<T> dups = new HashSet<T>();
    for (T t : list) {
        if (!ones.add(t)) {
            dups.add(t);
        }
    }
    List<T> result = new ArrayList<T>(dups.size() * 2);
    for (T t : list) {
        if (dups.contains(t)) {
            result.add(t);
        }
    }
    return result;
}
  • Создание нового списка с использованием Collection::removeAll:
public static <T> List<T> getDuplicates(List<T> list) {
    Set<T> ones = new HashSet<T>();
    Set<T> dups = new HashSet<T>();
    for (T t : list) {
        if (!ones.add(t)) {
            dups.add(t);
        }
    }
    ones.removeAll(dups); // оставить только уникальные элементы
    List<T> result = new ArrayList<T>(list);
    result.removeAll(ones); // удалить уникальные элементы
    return result;
}