выполнить проекцию в списке - PullRequest
1 голос
/ 19 января 2020

У меня есть список чисел, которые я группирую по количеству происшествий. Например, мой список { 1, 2, 1, 1, 2, 3 } сгруппированный список будет выглядеть так:

{ 
    { Key = 1, Value = { 1, 1, 1 } }, 
    { Key = 2, Value = { 2, 2 } }, 
    { Key = 3, Value = { 3 } } 
}

Вот код этой группировки:

Map<Integer, List<Integer>> groups = input.stream().collect(Collerctors.groupingBy(x -> x));

Теперь для каждой из этих групп, которые я хочу чтобы получить пары. Так что для 1 есть только одна пара, последняя 1 опущена. Для 2 у нас также есть одна пара, для 3 у нас ее нет. Поэтому я подумал о том, чтобы определить размер каждой группы и разделить его на 2. Наконец, мне нужно суммировать все эти результаты. Однако я не знаю, как выполнить такую ​​проекцию в java. В C# я бы сделал что-то вроде этого:

var result = groups.Select(x => x.ToList().Count / 2).Sum();

Полагаю, в Java я бы использовал collect -функцию, но я не смог ее получить:

Integer result = groups.stream().collect(...)

Ответы [ 2 ]

3 голосов
/ 19 января 2020

Прежде всего, вы можете связать counting Collector до groupingBy, так что значения Map будут равны количеству элементов в каждой группе.

Затем вы можете Stream по значениям, разделите на 2 и вычислите сумму.

input.stream()
     .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()))
     .values()
     .stream()
     .mapToLong(i -> i/2)
     .sum();

Возвращает 2 для выборочного ввода.

0 голосов
/ 19 января 2020

Я получил его на работу с помощью Collectors.summingInt:

Integer result = groups.entrySet()
    .stream()
    .collect(Collectors.summingInt(x -> x.getValue().size() / 2)
...