Как я могу отображать количество дубликатов в ArrayList - PullRequest
0 голосов
/ 05 декабря 2018

Рассмотрим ниже arraylist, который состоит из дубликатов.Как бы я отфильтровал целое число 89, которое встречалось 4 раза, например, 89: 4.Ожидаемый вывод 89: 4

List<Integer> list = Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21, 21, 61, 98, 15, 25, 41, 67,55, 89, 89, 89, 89 );         
Map<Integer ,Long > map = list.stream()
        .collect(Collectors.groupingBy(c ->c , Collectors.counting())) ;
map.forEach(   (k , v ) -> System.out.println( k + " : "+ v ));

// Я ожидаю вывода ниже 89: 4

// Фактические пары вывода (ключ, значения) приведенного выше фрагмента кодакак показано ниже 1: 2 98: 1 2: 1 67: 1 3: 1 5: 1 8: 1 41: 1 13: 1 15: 1 21: 2 55: 1 89: 4 25: 1 61: 1

Ответы [ 6 ]

0 голосов
/ 05 декабря 2018

Вы можете использовать Apache Bag

Определяет коллекцию, которая подсчитывает, сколько раз объект появляется в коллекции.Предположим, у вас есть сумка, которая содержит {a, a, b, c}.Вызов getCount (Object) для a вернет 2, в то время как вызов uniqueSet () вернет {a, b, c}.

Пример

 Bag<Integer> bag = new HashBag<>(
 Arrays.asList(1, 2, 3, 3, 3, 1, 4));         
 assertThat(2, equalTo(bag.getCount(1)));
0 голосов
/ 05 декабря 2018

Другой способ был бы таким:

Map<Integer, Integer> temp = new HashMap<>();
int maxCount = 0;
  for (Integer i : list) {
   maxCount = Integer.max(maxCount , temp.merge(i, 1, Integer::sum));
  }
int finalMax = maxCount;
temp.values().removeIf(v->v!= finalMax);

или


 Map<Integer, Integer> temp = new HashMap<>();
    int maxCount = 0;
    int maxKey = 0;
    for (Integer i : list) {
        int count = temp.merge(i, 1, Integer::sum);
        if (maxCount < count)
            maxKey = i;
        maxCount = Integer.max(maxCount , count);
    }
    System.out.println(maxKey + " :" + maxCount);
0 голосов
/ 05 декабря 2018

Если вы используете Eclipse Collections , вы можете использовать topOccurrences.

List<Integer> list = 
    Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21, 21, 61, 98, 15, 25, 41, 67,55, 89, 89, 89, 89 );
MutableList<ObjectIntPair<Integer>> top = Lists.adapt(list).toBag().topOccurrences(1);
System.out.println(top.makeString());

Если вам нужны все дубликаты, вы можете использовать selectDuplicates.Это отфильтровывает 1, 21 и 89.

MutableBag<Integer> dupes = Lists.adapt(list).toBag().selectDuplicates();
System.out.println(dupes.toStringOfItemToCount());

Вы также можете сделать это без упаковки примитивов.

IntList list =
    IntLists.mutable.with(1, 1, 2, 3, 5, 8, 13, 21, 21, 61, 98, 15, 25, 41, 67, 55, 89, 89, 89, 89);

MutableList<IntIntPair> top = list.toBag().topOccurrences(1);
System.out.println(top.makeString());

IntBag dupes = list.toBag().selectDuplicates();
System.out.println(dupes.toStringOfItemToCount());

Примечание: я являюсь коммиттером для коллекций Eclipse.

0 голосов
/ 05 декабря 2018

Короткая и удобная для памяти версия.У него действительно плохое big-O при O (n ^ 2), но для небольших списков обеспечивает лучшую производительность в средах с высокой степенью параллелизма и давлением GC, поскольку объекты HashMaps и Map.Entry занимают место и плохо используют кэширование ЦП:

import static java.util.Collections.frequency;
import static java.util.Comparator.comparingInt;
...
List<Integer> list = Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21, 21, 
        61, 98, 15, 25, 41, 67,55, 89, 89, 89, 89 );

list.stream()
  .max(comparingInt(x -> frequency(list, x)))
  .map(x -> x + " : " + frequency(list,x))
  .ifPresent(System.out::println);

Отпечатки 89 : 4 т.е. <most frequent int> : <num occurences>

0 голосов
/ 05 декабря 2018

Надеюсь, это поможет ...

List<Integer> list = Arrays.asList(1, 1, 2, 3, 5, 8, 13, 21, 21, 61,
            98, 15, 25, 41, 67,55, 89, 89, 89, 89 );
Optional<Map.Entry<Integer, Long>> max = list.stream()
            .collect(Collectors.groupingBy(obj -> obj, Collectors.counting()))
            .entrySet()
            .stream()
            .max(Comparator.comparing(Map.Entry::getValue));

if(max.isPresent()) {
    System.out.println(max.get());
}
0 голосов
/ 05 декабря 2018

Вы можете сделать это так,

Entry<Integer, Long> maxOccurence = list.stream()
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
    .entrySet().stream()
    .max(Comparator.comparing(Map.Entry::getValue))
    .orElseThrow(IllegalArgumentException::new);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...