Потоковая группировка значений
Есть ли нетерминальная версия groupingBy
или какой-то другой аккуратный способ для потоковой передачи в результате записи / значения карты?
Я чувствую, что хочу просмотреть значения после groupingBy
но лучшее, что я мог придумать, это не красиво:
StreamEx.ofValues(
StreamEx.of(0, 1, 2, 4).groupingBy(i -> i % 2)
).mapToInt(ii -> IntStreamEx.of(ii).sum())
// RESULT: [6, 1]
2 ответа
Выполнение этого в одном поточном конвейере, вероятно, потребовало бы, чтобы требуемая операция действовала как полный барьер: чтобы сгруппировать значения, нам нужно обработать их все, чтобы увидеть, какие значения являются четными и нечетными (и иметь возможность их суммировать).
Таким образом, вероятно, предпочтительнее использовать временную структуру данных для хранения количества четных и нечетных значений, которое в этом случае будет Map<Integer, Integer>
или даже Map<Boolean, Integer>
(где, например, ключ будет true
для четных значений и false
для нечетных значений, используя Collectors.partitioningBy
).
Обратите внимание, что вам не нужно использовать библиотеку StreamEx здесь. Вы можете сделать это напрямую через Stream API:
public static void main(String[] args) {
Map<Integer, Integer> map =
Stream.of(0, 1, 2, 4)
.collect(Collectors.groupingBy(
i -> i % 2,
Collectors.summingInt(i -> i)
));
Stream<Integer> stream = map.values().stream();
}
summingInt
вероятно, лучшее решение для этого конкретного вопроса.
Я полагаю, я упростил проблему, используя в своем примере целые числа. Моя настоящая проблема заключалась в объединении объектов, а не значений int. я нашел collectingAndThen
быть весьма полезным. Это работает так:
Function<List<Integer>, Integer> merge = ii -> ii.stream().mapToInt(i -> i).sum();
Stream.of(0, 1, 2, 4).collect(groupingBy(i -> i % 2, collectingAndThen(toList(), merge))).values();