本文介绍了映射Collectors.groupingBy()中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了这个例子,我们假设我有一个具有两个属性的简单类型Tuple:

For the sake of this example, let's assume I have a simple type Tuple with two attributes:

interface Tuple<T, U> {
    T getFirst();
    U getSecond();
}

现在,我想将(first, second)元组的集合转换为映射,该映射将每个first值映射到元组中包含的具有该特定first值的所有second值的集合.方法groupSecondByFirst()显示了可能要执行的操作:

Now I want to transform a collection of (first, second) tuples into a map which maps each first value to a set of all second values contained in tuples with that specific first value. The method groupSecondByFirst() shows a possible implementation doing what I want:

<T, U> Map<T, Set<U>> groupSecondByFirst(Set<Tuple<T, U>> tuples) {
    Map<T, Set<U>> result = new HashMap<>();

    for (Tuple<T, U> i : tuples) {
        result.computeIfAbsent(i.getFirst(), x -> new HashSet<>()).add(i.getSecond());
    }

    return result;
}

如果输入为[(1, "one"), (1, "eins"), (1, "uno"), (2, "two"), (3, "three")],则输出为{ 1 = ["one", "eins", "uno"], 2 = ["two"], 3 = ["three"] }

If the input was [(1, "one"), (1, "eins"), (1, "uno"), (2, "two"), (3, "three")] the output would be { 1 = ["one", "eins", "uno"], 2 = ["two"], 3 = ["three"] }

我想知道是否以及如何使用streams框架来实现这一点.我得到的最好的结果是以下表达式,该表达式返回一个映射,该映射包含完整的元组作为值,而不仅仅是它们的second元素:

I would like to know whether and how I can implement this using the streams framework. The best I got is the following expression, which returns a map which contains the full tuple as values and not just their second elements:

Map<T, Set<Tuple<T, U>>> collect = tuples.stream().collect(
    Collectors.groupingBy(Tuple::getFirst, Collectors.toSet()));

推荐答案

我找到了解决方案;它涉及到Collections.mapping(),它可以包装收集器并在流上应用映射功能,以将元素提供给包装的收集器:

I found a solution; It involves Collections.mapping(), which can wrap a collector and apply mapping function over stream to supply elements to the wrapped collector:

static <T, U> Map<T, Set<U>> groupSecondByFirst(Collection<Tuple<T, U>> tuples) {
    return tuples
        .stream()
        .collect(
            Collectors.groupingBy(
                Tuple::getFirst,
                Collectors.mapping(
                    Tuple::getSecond,
                    Collectors.toSet())));
}

这篇关于映射Collectors.groupingBy()中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 02:34