Как метод retainAll из класса Set МОЖЕТ НЕ игнорировать повторяющиеся элементы в общем списке?

#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 интерфейса может быть следующим:

  1. Создайте карту частот для list1
  2. Повторите list2 и проверьте, доступен ли его элемент на карте, и частота gt; 0.
  3. Если да, уменьшите частоту и добавьте элемент в результирующий список.
 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]