Как удалить уникальные значения из списка List
Имеется 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)
Ответы (2 шт):
Заводите 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);
}
Подобного рода вопросы задаются достаточно часто в разных формулировках, например:
- Получить из строки только уникальные элементы
- Создать новый список из исходного , который должен состоять из неповторяющихся чисел изначального списка и т.д.
Решение с использованием двух сетов (в стиле 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;
}