且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在java 8中按多个字段名称分组

更新时间:2023-02-19 08:02:37

这里有几个选项.最简单的方法是链接您的收藏家:

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 内部.此代码使用 record 但它可以很容易地成为 JEP 359 之前的 Java 版本中的类(定义了 equalshashCode)补充:

A second option is to define a class that represents the grouping. This can be inside Person. This code uses a record but it could just as easily be a class (with equals and hashCode defined) in versions of Java before JEP 359 was added:

class Person {
    record NameAge(String name, int age) { }

    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 如果您使用这些库中的一个,那么您可以将映射的键设为一对名称和年龄:

Finally if you don't want to implement your own group record then many of the Java frameworks around have a pair class designed for 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));

我个人认为通用元组没有多大价值,因为记录在该语言中可用,因为记录可以更好地显示意图并且只需要很少的代码.

Personally I don't really see much value in generic tuples now that records are available in the language as records display intent better and require very little code.