#java #list #set
Вопрос:
Есть много вопросов, связанных с игнорированием повторяющихся элементов в списке, но я хочу сохранить повторяющиеся элементы в общем списке из метода retainAll из набора.
Как я могу получить все элементы, включая повторяющиеся строки, в общем списке?
Я хочу, чтобы общий список включал повторяющиеся строки «a» в виде отдельных элементов (размер списка 5) : «a», «a», «e», «f», «j»
но фактический общий список возвращается с одним «a» (размер списка: 4) : «a», «e», «f», «j»
Listlt;Stringgt; list1 = new ArrayListlt;gt;(); list1.add("a"); list1.add("k"); list1.add("s"); list1.add("f"); list1.add("a"); list1.add("j"); list1.add("e"); Listlt;Stringgt; list2 = new ArrayListlt;gt;(); list2.add("a"); list2.add("a"); list2.add("e"); list2.add("f"); list2.add("j"); Setlt;Stringgt; common = new HashSetlt;gt;(list1); common.retainAll(list2);
Комментарии:
1. Наборы не содержат дубликатов. Вы пробовали составить Список?
2. Список, кажется, возвращает элементы так, как я хочу. Спасибо за это! @shmosel
3. Как я могу определить, имеют ли два списка (common и list2) одинаковые элементы, независимо от порядка в Java? Я вижу вопрос в Python с использованием Collections.counter (), но что я могу использовать для Java? @shmosel
4. Вы можете отсортировать их перед сравнением. Или скопируйте их в набор, если количество не имеет значения. Или используйте мультисет.
Ответ №1:
Решение для реализации пользовательского retainAll
интерфейса может быть следующим:
- Создайте карту частот для
list1
- Повторите
list2
и проверьте, доступен ли его элемент на карте, и частота gt; 0. - Если да, уменьшите частоту и добавьте элемент в результирующий список.
public staticlt;Tgt; Listlt;Tgt; retainAll(Listlt;Tgt; list1, Listlt;Tgt; list2) { Maplt;T, Longgt; freqMap = list1 .stream() .collect(Collectors.groupingBy(x -gt; x, Collectors.counting())); return list2 .stream() .filter(x -gt; Optional.ofNullable( freqMap.computeIfPresent(x, (k, v) -gt; v - 1) ).orElse(-1L) gt;= 0L ) .collect(Collectors.toList()); }
Тест:
Listlt;Stringgt; list1 = Arrays.asList("a", "k", "s", "f", "e", "j", "a"); Listlt;Stringgt; list2 = Arrays.asList("a", "f", "e", "j", "a", "a"); Listlt;Stringgt; common = retainAll(list1, list2); System.out.println(common);
Выход:
[a, f, e, j, a]