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