我正在使用Stream重写一个方法,但我有点卡住了。对于短篇小说,它是一种用于检索玩家可用技能的方法。整个技能列表存储在播放器模板中(getTemplate(),列表可通过getTemplate()。getSkills())访问。玩家还拥有自己已知的技能,存储在Map中(在这种情况下,我只使用getSkillLevel,如果已知则返回技能级别,如果未知则返回-1)。
必须按某些条件进行过滤,例如:
GeneralSkillNode是一个包含以下信息的容器:
getTemplate()。getSkills()是这个玩家可以学习的全部可学习技能(这里列出了每个技能条目,无论级别如何),这是一个List。
问题来自于它目前注册的所有技能等级范围。假设给定技能id有18个级别(1-1-5,1-2-5,1-3-5,... 1-18-80),它将为技能id添加18个GeneralSkillNode 。我需要按技能ID进行过滤,并且只保留每个技能ID,最大可能等级(可以测试,如果你按照我的解释,使用getValue())。如果我使用具有.max的比较器(,它只会检索单个技能的最高级别。
我搜索最优雅的方式来做到这一点。在此先感谢您的帮助!
这是我目前的结果:
/**
* @return a {@link Collection} of all available {@link GeneralSkillNode}s (being general or autoGet) <b>of maximal level</b> for this {@link Player}.
*/
public Collection<GeneralSkillNode> getAllAvailableSkills()
{
final List<GeneralSkillNode> result = new ArrayList<>();
getTemplate().getSkills().stream().filter(s -> s.getMinLvl() <= getLevel()).forEach(s ->
{
final int playerSkillLevel = getSkillLevel(s.getId());
if (playerSkillLevel == -1 || playerSkillLevel < s.getValue())
result.add(s);
});
return result;
}
编辑:感谢您的帮助,最终版本现在看起来像这样:
/**
* @return a {@link Collection} of all available {@link GeneralSkillNode}s (being general or autoGet) <b>of maximal level</b> for this {@link Player}.
*/
public Collection<GeneralSkillNode> getAllAvailableSkills()
{
final List<GeneralSkillNode> result = new ArrayList<>();
getTemplate().getSkills().stream().filter(s -> s.getMinLvl() <= getLevel()).collect(Collectors.groupingBy(s -> s.getId(), Collectors.maxBy(Comparator.comparing(s -> s.getValue())))).forEach((i, s) ->
{
final int playerSkillLevel = getSkillLevel(i);
if (playerSkillLevel == -1 || playerSkillLevel < s.get().getValue())
result.add(s.get());
});
return result;
}
答案 0 :(得分:2)
要获得每项技能的最高级别,您可以groupingBy
分隔每项技能,然后maxBy
以获得每种技能的最高级别。
getTemplate().getSkills().stream().filter(s -> s.getMinLvl() <= getLevel())
.collect(Collectors.groupingBy(s -> s.getId(),
Collectors.maxBy(Comparator.comparing(s -> s.getValue()))));