微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决在java 8中按多个字段名称分组

你有几个选择。最简单的方法链接您的收藏家:

Map<String, Map<Integer, List<Person>>> map = people
    .collect(Collectors.groupingBy(Person::getName,
        Collectors.groupingBy(Person::getAge));

然后要获取名为 Fred 的 18 岁人的列表,您可以使用:

map.get("Fred").get(18);

第二种选择是定义一个表示分组的类。这可以在 Person 内部。此代码使用了 ,record但在添加 JEP 359 之前,它可以很容易地成为Java 版本中的类(具有equalshashCode定义):

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

Map<Pair<String, Integer>, List<Person>> map =
    people.collect(Collectors.groupingBy(p -> Pair.of(p.getName(), p.getAge())));

并检索:

map.get(Pair.of("Fred", 18));

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

解决方法

我从 POJO 中找到了按某些字段名称对对象进行分组的代码。下面是代码:

public class Temp {

    static class Person {

        private String name;
        private int age;
        private long salary;

        Person(String name,int age,long salary) {

            this.name = name;
            this.age = age;
            this.salary = salary;
        }

        @Override
        public String toString() {
            return String.format("Person{name='%s',age=%d,salary=%d}",name,age,salary);
        }
    }

    public static void main(String[] args) {
        Stream<Person> people = Stream.of(new Person("Paul",24,20000),new Person("Mark",30,30000),new Person("Will",28,28000),new Person("William",28000));
        Map<Integer,List<Person>> peopleByAge;
        peopleByAge = people
                .collect(Collectors.groupingBy(p -> p.age,Collectors.mapping((Person p) -> p,toList())));
        System.out.println(peopleByAge);
    }
}

输出是(这是正确的):

{24=[Person{name='Paul',age=24,salary=20000}],28=[Person{name='Will',age=28,salary=28000},Person{name='William',salary=28000}],30=[Person{name='Mark',age=30,salary=30000}]}

但是如果我想按多个字段分组怎么办?在该 POJO 中groupingBy()实现equals()方法之后,我显然可以在方法中传递一些 POJO,但是有没有其他选项,例如我可以按给定 POJO 中的多个字段进行分组?

例如,就我而言,我想按姓名和年龄分组。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。