坚持使用java8 lambda表达式

Fen*_*eng 6 java lambda java-8

Map<Integer,Doctor> docLib=new HashMap<>();要保存课程Doctor.

Class Doctor已经methods:getSpecialization()返回String,
getPatients()返回类的集合Person.

在main方法中,我键入:

public Map<String,Set<Person>> getPatientsPerSpecialization(){
    Map<String,Set<Person>> res=this.docLib.entrySet().stream().
                         map(d->d.getValue()).
                         collect(groupingBy(d->d.getSpecialization(),
                                            d.getPatients()) //error
                                 );
   return res;
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我有问题groupingBy,我尝试将相同的值d发送给方法,但这是错误的.怎么解决这个?

Era*_*ran 5

您需要第二个收集器用于该映射:

public Map<String,Set<Person>> getPatientsPerSpecialization(){
    return this.docLib
               .values()
               .stream()
               .collect(Colectors.groupingBy(Doctor::getSpecialization,
                                             Collectors.mapping(Doctor::getPatients,toSet()))
                       );
}
Run Code Online (Sandbox Code Playgroud)

编辑:

我认为我的原始答案可能是错误的(如果不能测试它很难说).因为Doctor::getPatients返回一个Collection,我想我的代码可能会返回一个Map<String,Set<Collection<Person>>>而不是所需的代码Map<String,Set<Person>>.

解决这个问题的最简单方法是Map再次迭代它以产生所需的Map:

public Map<String,Set<Person>> getPatientsPerSpecialization(){
    return this.docLib
               .values()
               .stream()
               .collect(Colectors.groupingBy(Doctor::getSpecialization,
                                             Collectors.mapping(Doctor::getPatients,toSet()))
                       )
               .entrySet()
               .stream()
               .collect (Collectors.toMap (e -> e.getKey(),
                                           e -> e.getValue().stream().flatMap(c -> c.stream()).collect(Collectors.toSet()))
                        );
}
Run Code Online (Sandbox Code Playgroud)

也许有一种方法可以通过单个Stream管道获得相同的结果,但我现在无法看到它.

  • 而不是`docLib.entrySet().stream().map(d-> d.getValue())`你可以编写`docLib.values().stream()`. (2认同)