卡在lambda表达式和地图上 [英] Stuck with lambda expression and Map

查看:41
本文介绍了卡在lambda表达式和地图上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有Person类:

import java.util.*;
public class Person {
    private String name;
    Map<String,Integer> Skills=new HashMap<>(); // skill name(String) and level(int)

    public String getName(){
        return this.name;
    }
    public Map<String,Integer> getSkills(){
        return this.Skills;
    }
}

App类:

import java.util.*;
import java.util.Map.Entry;
import static java.util.stream.Collectors.*;
import static java.util.Comparator.*;
public class App {
    private List<Person> people=new ArrayList<>(); // the people in the company

    public Map<String,Set<String>> PeoplePerSkill(){
        return this.people.stream().collect(groupingBy(p-> p.getSkills().keySet() //<-get  
                                                                           //^problem here
                                  ,mapping(Person::getName,toSet())));
    }
}

App类中,PeoplePerSkill方法需要按技能返回人员名称的Set.这意味着一项技能可以被很多人拥有.

In the App class the PeoplePerSkill method need to return the Set of people names per skill. It means a skill could be owned by many people.

我坚持使用groupingBy(p->p..........., ),只是无法获得技能名称的String,我尝试了很多方法,但是事情变得陌生了:(.

I stuck with the groupingBy(p->p..........., ) I just can't get the String of skill's name, I tried so many ways but things get way stranger :(.

顺便说一句,目前我的代码返回Map<Object, Set<String>>

By the way, currently my code returns Map<Object, Set<String>>

推荐答案

您可以通过平面映射来完成此操作,尽管它看起来可能并不十分漂亮:

You can do it via flat-mapping, though it probably doesn't look very beautiful:

public Map<String,Set<String>> PeoplePerSkill(){
    return this.people.stream()
        .<Entry<String, String>>flatMap(p -> 
            p.getSkills().keySet()
                .stream()
                .map(s -> new AbstractMap.SimpleEntry<>(s, p.getName())))
        .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toSet())));
}

在这里flatMap创建一个对(skill, person name)对的流,它们的收集方式与您非常相似.我正在使用AbstractMap.SimpleEntry类来表示该对,您可以使用其他一些东西.

Here flatMap creates a stream of pairs (skill, person name), which are collected in the manner quite similar to yours. I'm using the AbstractMap.SimpleEntry class to represent the pair, you may use something else.

使用我的 StreamEx 库,可以更轻松地解决此任务:

Using my StreamEx library this task can be solved prettier:

return StreamEx.of(this.people)
        .mapToEntry(p -> p.getSkills().keySet(), Person::getName)
        .flatMapKeys(Set::stream)
        .grouping(toSet());

内部几乎一样,只是语法糖.

Internally it's almost the same, just syntactic sugar.

更新:似乎我原来的解决方案是错误的:它返回了地图person_name -> [skills],但是如果我正确理解了OP,他会想要地图skill -> [person_names].答案已编辑.

Update: seems that my original solution was wrong: it returned map person_name -> [skills], but if I understand the OP correctly, he wants map skill -> [person_names]. The answer edited.

这篇关于卡在lambda表达式和地图上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆