更新时间:2023-02-19 07:57:16
这里有几个选项。最简单的是链接你的收藏家:
You have a few options here. The simplest is to chain your collectors:
Map<String, Map<Integer, List<Person>>> map = people
.collect(Collectors.groupingBy(Person::getName,
Collectors.groupingBy(Person::getAge));
然后,要获得一份名为Fred的18岁人员名单,您将使用:
Then to get a list of 18 year old people called Fred you would use:
map.get("Fred").get(18);
第二个选项是定义一个表示分组的类。这可以在Person中:
A second option is to define a class that represents the grouping. This can be inside 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框架都有一个对
类,专为此类事物而设计。例如: apache commons pair 如果你使用这些库中的一个,然后你可以为地图的关键字创建一对名称和年龄:
Finally if you don't want to implement your own group class then many of the Java frameworks around have a pair
class designed for exactly this type of thing. For example: apache commons pair If you use one of these libraries then you can make the key to the map a pair of the name and age:
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设计完全相反:它们隐藏意图而不是暴露它。
Personally I really dislike these tuple libraries. They seem to be the exact opposite of good OO design: they hide intent instead of exposing it.
说过你可以通过定义自己的分组来组合后两个选项类,但通过扩展 Pair
来实现它 - 这为您节省了很多定义等于
等所涉及的工作并隐藏使用元组只是一个方便的实现细节,就像任何其他集合一样。
Having said that you can combine the second two options by defining your own grouping class but implementing it by just extending Pair
- that saves you a lot of the work involved in defining equals
etc and hides the use of the tuple as just a convenient implementation detail like any other collection.
祝你好运。