我从 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", 28, 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', age=28, salary=28000}], 30=[Person{name='Mark', age=30, salary=30000}]}
但是如果我想按多个字段分组怎么办?我显然可以在 groupingBy()
方法中传递一些 POJO 实现 equals()
POJO 中的方法,但是是否有任何其他选项,比如我可以按给定 POJO 中的多个字段分组?
例如,在我的例子中,我想按姓名和年龄分组。
原文由 Mital Pritmani 发布,翻译遵循 CC BY-SA 4.0 许可协议
您在这里有几个选择。最简单的是链接你的收集器:
然后要获得名为 Fred 的 18 岁人员的列表,您可以使用:
第二种选择是定义一个代表分组的类。这可以在 Person 内部。此代码使用
record
但它可以很容易地成为一个类(在 J35 的版本中添加equals
和hashCode
定义):然后你可以使用:
并搜索
最后,如果您不想实现自己的组记录,那么周围的许多 Java 框架都有一个
pair
专为此类事物设计的类。例如: apache commons pair 如果您使用这些库中的一个,那么您可以将地图的键设为一对姓名和年龄:并检索:
就我个人而言,我并没有真正看到通用元组有多大价值,因为记录可以在语言中使用,因为记录可以更好地显示意图并且需要很少的代码。