Java 转换地图<;键,列表<;价值>&燃气轮机;映射<;关键、价值>;

Java 转换地图<;键,列表<;价值>&燃气轮机;映射<;关键、价值>;,java,java-8,java-stream,Java,Java 8,Java Stream,我所拥有的: 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));

我所拥有的:

    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()));
免责声明:

我知道这个用例有点奇怪,因为我根据长度排序,还通过比较名称的长度来使用compareTo。我想这对这个问题无关紧要,因为我总是会得到一张
地图。

问题是:如何获得
Map

事实上,您的要求没有意义。您希望按属性分组,这意味着它不一定是双射函数。因此,默认情况下,结果映射的值类型是一个列表。如果您知道所应用的函数是双射函数,那么可以提供另一个下游收集器/或使用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());}));

如果你有两个相同长度的名字呢?事实上你的要求没有意义。您希望按属性分组,这意味着它不一定是双射函数。因此,默认情况下,结果映射的值类型是一个列表。如果您知道所应用的函数是双射函数,则可以提供另一个下游收集器/或使用
toMap
收集器,并将其作为参数(IMO的最佳选项)。如果两个名称完全相等(根据compareTo),则不会将此人添加到列表中,因为它是一个集合,但是,对于如何平面映射列表的问题,这并不是关键。用于分组的属性是长度。因此,您可以有两个不同的名称(因此在集合中)具有相同的长度…您能给出一个代码示例吗?p、 s:我总是得到一个列表,即使该列表只包含一个元素。这是否有意义并不重要,因为清单仍然存在。那我怎么才能平面地图呢?谢谢!我试试这个。如果用例有点太混乱,我会改变它。正是我需要的。谢谢你,好先生。
@Override
public int compareTo(Person o) {

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

    return cmp;
}
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)}