我被阻止使用Java 函数式编程来构建地图。在我的用例中,这只是一个例子,我想构建一个Map<Integer, Map<Integer, List<Person>>>从List<Person>.
第一步很简单:我首先构建一个Map<Integer, List<person>>.
然后我想添加一个新的分组级别,以便生成一个新的 Map : Map<Integer, Map<Integer, List<person>>>。
重点是:如何正确使用所有 Collectors 功能(groupingBy、映射,也许还有其他功能)来添加新的分组级别?我所有的尝试都失败了:编译器总是告诉我我提供的所有函数都不符合它的预期。
这是代码,简要地说:
首先是一个 Person 类,然后是一个快速构建 List 的方法:
public class Person {
private long id;
privae String firstName;
private String lastName;
private Date birthDate;
private int alea;
...
此方法(位于 DataBuilder 类中)仅构建一个 Person 列表以向 Main 类提供数据:
public List<Person> getPersons() {
List<Person> persons = new ArrayList<>();
Supplier<Person> person = Person::new;
for (int cpt = 0; cpt < 10; cpt++) {
Person p = person.get();
p.setId(cpt);
p.setFirstName("fn" + cpt);
p.setLastName("ln" + cpt);
p.setBirthDate(new Date(119, cpt, 10 + cpt));
p.setAlea(cpt % 2);
persons.add(p);
}
return persons;
}
在 Main 中,构建第一层 Map 不是问题:
public static void main(String[] args) {
DataBuilder db = new DataBuilder();
List<Person> persons = db.getPersons();
Map<Integer, List<Person>> mapAleaPerson = persons.stream()
.collect(Collectors.groupingBy(Person::getAlea,
Collectors.mapping(p -> p, Collectors.toList())));
mapAleaPerson.forEach((k,v) -> System.out.printf("%n%s contains %s%n", k, v));
结果在控制台中正常:
0 contains [Person [id=0, firstName=fn0, lastName=ln0, alea=0], Person [id=2, firstName=fn2, lastName=ln2, alea=0], Person [id=4, firstName=fn4, lastName=ln4, alea=0], Person [id=6, firstName=fn6, lastName=ln6, alea=0], Person [id=8, firstName=fn8, lastName=ln8, alea=0]]
现在我想添加一个新的分组级别。我选择了 BirthDate 的年份,这是 Person 对象的另一个属性。
每次编译器都会因为不兼容的 Function 类型而返回错误。
我发现添加新分组级别的唯一方法是使用旧的 Java 代码和外部循环在 Map 的 Map 中添加和分组数据。
在旧 Java 中嵌入 FP 令人失望!!
有人知道用纯 FP 做所有这些吗?
真正令人惊讶的是,groupingBy与构建第一个 Map 本身的方式相比,嵌套语句的简单性。
为什么我们不再需要指定mappingandCollectors.toList()了?
慕后森
宝慕林4294392
随时随地看视频慕课网APP
相关分类