将Map<Key, List<Value>>转换为Map<Key, Value>

4

我的情况:

    SortedSet<Person> ss = new TreeSet<>();

    ss.add(new Person("John", "Doe", 20));
    ss.add(new Person("Max", "Power", 26));
    ss.add(new Person("Bort", "Bort", 30));
    ss.add(new Person("Scorpio", "McGreat", 56));

    Map<Integer, List<Person>> list = ss.stream().collect(Collectors.groupingBy(p -> p.name.length()));

我需要将Map转换为Map<Integer, Person>。我知道我需要使用flatMap来完成这个任务,但我不知道如何操作。 到目前为止我尝试过的方法: 获取值集并对其进行flatMap操作。
Map <Integer, Person> list2 = list.values()
                                    .stream()
                                    .flatMap(f -> f.stream())
                                    .collect(Collectors.groupingBy(f -> f.name.length()); //doesn't work

问题: 据我所知,当你通过流创建映射表时,Java将返回值作为列表,那么如何对这些列表进行flatMap操作?

额外信息: compareTo的实现

@Override
public int compareTo(Person o) {

    int cmp = this.surname.compareTo(o.surname);
    if(cmp == 0){
        cmp = this.name.compareTo(o.name);
    }

    return cmp;
}

声明:

我知道这个使用案例有点奇怪,因为我根据长度排序,并通过比较名称的长度来使用 compareTo。在我看来,对于这个问题,这并不重要,因为我总是会得到一个 Map<Key, List<Value>>。 问题是:如何获得 Map<Key,Value>


1
如果你有两个长度相同的名字,会怎么样? - Alexis C.
实际上,您的要求没有意义。您想按属性分组,这意味着它不一定是双射函数。因此,生成的映射值的类型默认为列表。如果您知道应用的函数是双射的,则可以提供另一个下游收集器/或使用toMap收集器,将抛出合并器作为参数(在我看来是最好的选择)。 - Alexis C.
如果两个名称根据compareTo完全相等,则不会将Person添加到列表中,因为它是一个Set,但在我看来,这对于如何flatMap列表的问题并不关键。 - SklogW
你用来分组的属性是长度。因此,你可以有两个不同的名称(因此在集合中)具有相同的长度... - Alexis C.
你能给一个代码示例吗?附注:即使该列表只包含一个元素,我始终会得到一个列表。我认为这是否有意义并不重要,因为列表仍然存在。那么我该如何使用flatMap呢? - SklogW
1个回答

3
事实上,您的要求并没有意义。您想按属性分组,这意味着它不一定是双射函数。因此,由默认情况下,生成的映射中的值类型为列表。如果您知道所应用的函数是双射的,可以提供另一个下游收集器/或使用toMap收集器,将抛出合并器作为参数(在我看来是最好的选项)。
例如:
Map<Integer, Person> list = 
    ss.stream()
      .collect(Collectors.toMap(p -> p.surname.length(), 
                                p -> p, 
                                (p1, p2) -> {throw new IllegalStateException("Duplicate key with length " + p1.surname.length());}));

您的情况下的输出:

{3=(John, Doe, 20), 4=(Bort, Bort, 30), 5=(Max, Power, 26), 7=(Scorpio, McGreat, 56)}

谢谢!我会尝试这个。如果使用案例有点混乱,我会进行更改。正是我所需要的。非常感谢您。 - SklogW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接