3 回答
TA贡献1757条经验 获得超7个赞
您在这里有一些选择。最简单的方法是链接您的收藏家:
Map<String, Map<Integer, List<Person>>> map = people
.collect(Collectors.groupingBy(Person::getName,
Collectors.groupingBy(Person::getAge));
然后,要使用18岁的年轻人Fred的清单,您可以使用:
map.get("Fred").get(18);
第二种选择是定义一个代表分组的类。这可以在Person内部:
class Person {
public static class NameAge {
public NameAge(String name, int age) {
...
}
// must implement equals and hash function
}
public NameAge getNameAge() {
return new NameAge(name, age);
}
}
然后,您可以使用:
Map<NameAge, List<Person>> map = people.collect(Collectors.groupingBy(Person::getNameAge));
并搜索
map.get(new NameAge("Fred", 18));
最后,如果您不想实现自己的组类,那么周围的许多Java框架都有一个pair专门用于此类事情的类。例如:apache commons pair如果您使用这些库之一,则可以将地图的名称和年龄配对:
Map<Pair<String, Integer>, List<Person>> map =
people.collect(Collectors.groupingBy(p -> Pair.of(p.getName(), p.getAge())));
并使用:
map.get(Pair.of("Fred", 18));
我个人真的不喜欢这些元组库。它们似乎与良好的OO设计完全相反:它们隐藏意图而不是公开意图。
话虽如此,您可以通过定义自己的分组类来组合后两个选项,而仅通过扩展即可实现Pair-从而节省了很多定义equals等工作,并且将元组的使用隐藏为任何其他便捷的实现细节其他集合。
祝好运。
TA贡献1843条经验 获得超7个赞
这里看一下代码:
您可以简单地创建一个功能,让它为您完成工作,一种功能样式!
Function<Person, List<Object>> compositeKey = personRecord ->
Arrays.<Object>asList(personRecord.getName(), personRecord.getAge());
现在,您可以将其用作地图:
Map<Object, List<Person>> map =
people.collect(Collectors.groupingBy(compositeKey, Collectors.toList()));
干杯!
TA贡献1864条经验 获得超2个赞
该groupingBy方法具有的第一个参数是Function<T,K>:
@param <T>输入元素的类型
@param <K>键的类型
如果在您的代码中将lambda替换为匿名类,则可以看到以下内容:
people.stream().collect(Collectors.groupingBy(new Function<Person, int>() {
@Override
public int apply(Person person) {
return person.getAge();
}
}));
刚才更改输出参数<K>。例如,在这种情况下,我使用了org.apache.commons.lang3.tuple中的pair类按名称和年龄进行分组,但是您可以根据需要创建自己的类以过滤组。
people.stream().collect(Collectors.groupingBy(new Function<Person, Pair<Integer, String>>() {
@Override
public YourFilter apply(Person person) {
return Pair.of(person.getAge(), person.getName());
}
}));
最后,用lambda back替换后,代码如下所示:
Map<Pair<Integer,String>, List<Person>> peopleByAgeAndName = people.collect(Collectors.groupingBy(p -> Pair.of(person.getAge(), person.getName()), Collectors.mapping((Person p) -> p, toList())));
添加回答
举报