有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

收集器中的java映射值。分组方式()

在本例中,假设我有一个简单类型Tuple,具有两个属性:

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

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

<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"] }

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

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

共 (1) 个答案

  1. # 1 楼答案

    我找到了解决办法;它涉及Collections.mapping(),它可以包装收集器并在流上应用映射函数,以向包装的收集器提供元素:

    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())));
    }