Подсчет элементов из карты, для которой задано значение - PullRequest
0 голосов
/ 31 мая 2018

У меня есть список предметов, как показано ниже

List<SomeModel> smList = new ArrayList<>();

    smList.add(new SomeModel(1L,6.0f));//id = 1L and capacity = 6.0f
    smList.add(new SomeModel(2L,7.0f));
    smList.add(new SomeModel(3L,7.0f));
    smList.add(new SomeModel(4L,7.0f));

Теперь я преобразовываю этот список в

Map<Float, Set<Long>> complexList = new HashMap<>();
        complexList = smList.stream().collect(Collectors.groupingBy(SomeModel::getCapacity,
                Collectors.mapping(SomeModel::getId, Collectors.toSet())));

здесь complexList выдает вывод как

7.0=[2, 3, 4]
6.0=[1]

Теперь мне нужно посчитать количество значений для каждой «емкости», выдавая вывод как

7.0=3
6.0=1

Я пытался

Map<Float, Long> complexCount = complexList.entrySet().stream().
                collect(Collectors.groupingBy(Map.Entry::getKey, 
                        Collectors.mapping(Map.Entry::getValue, Collectors.counting())));
        complexCount.forEach((k,v)->System.out.println(k+"="+v));

, и он выдает

6.0=1
7.0=1

Я долженошибаться в понимании потоков или не использовать правильные методы.Кто-нибудь может предложить подход или решение?Ссылка на потоки также будет полезна.

Ответы [ 4 ]

0 голосов
/ 31 мая 2018

Если все, что вы хотите сделать, это напечатать каждый ключ карты вместе с размером соответствующего значения, то нет необходимости снова выполнять потоковую передачу, поскольку это приводит к ненужным накладным расходам.просто переберите слишком много complexList и напечатайте его так:

complexList.forEach((k,v)->System.out.println(k+"="+v.size()));

или если вы действительно хотите карту, то можно также сделать:

Map<Float, Integer> accumulator = new HashMap<>();
complexList.forEach((k,v)->accumulator.put(k, v.size()));
0 голосов
/ 31 мая 2018

Попробуйте,

Map<Float, Integer> countByKey = sourceMap.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().size()));
0 голосов
/ 31 мая 2018

Вы можете использовать несколько Collector с и collectingAndThen().И даже не нужно собирать его на промежуточную карту:

import static java.util.stream.Collectors.*;

/* ... */

Map<Float, Integer> collect = smList.stream()
    .collect(groupingBy(SomeModel::getCapacity,
        collectingAndThen(
            mapping(SomeModel::getId, toSet()),
            Set::size
        )
    ));
0 голосов
/ 31 мая 2018

Вы делаете это очень сложным.Более простое решение ниже:

Map<Float, Long> complexCount = complexList
.entrySet()
.stream()
.collect(Collectors.toMap(
               Map.Entry::getKey,
               entry -> new Long(entry.getValue().size())
        )
);

Здесь вам просто нужно позвонить Collectors.toMap.Он имеет две функции, одну для ключа и другую для значения карты.

Если нет ограничений на использование Long в качестве типа значения Map, тогда:

 Map<Float, Integer> complexCount = complexList
    .entrySet()
    .stream()
    .collect(Collectors.toMap(
                   Map.Entry::getKey,
                   entry -> entry.getValue().size()
            )
    );
...