如何使用Java8流API转换代码?

如何使用Java8流API转换代码?,java,java-8,java-stream,Java,Java 8,Java Stream,我正在写一个简单的方法来打印一系列游戏结果的统计数据。每个游戏都有一个结果列表,其中包含根据游戏结果的枚举。 我的讲师在我的代码中注释了TODO: public static void printStatistics(List<Game> games) { float win = 0; float lose = 0; float draw = 0; float all = 0; //TODO: should be implemented /w

我正在写一个简单的方法来打印一系列游戏结果的统计数据。每个游戏都有一个结果列表,其中包含根据游戏结果的枚举。 我的讲师在我的代码中注释了TODO:

public static void printStatistics(List<Game> games) {
    float win = 0;
    float lose = 0;
    float draw = 0;
    float all = 0;

    //TODO: should be implemented /w stream API
    for (Game g : games) {
        for (Outcome o : g.getOutcomes()) {
            if (o.equals(Outcome.WIN)) {
                win++;
                all++;
            } else if (o.equals(Outcome.LOSE)) {
                lose++;
                all++;
            } else {
                draw++;
                all++;
            }
        }
    }
    DecimalFormat statFormat = new DecimalFormat("##.##");

    System.out.println("Statistics: The team won: " + statFormat.format(win * 100 / all) + " %, lost " + statFormat.format(lose * 100 / all)
            + " %, draw: " + statFormat.format(draw * 100 / all) + " %");

}
publicstaticvoidprintstatistics(列表游戏){
浮动赢=0;
浮动损失=0;
浮点数=0;
浮动所有=0;
//TODO:应该实现/w流API
对于(游戏g:游戏){
对于(结果o:g.getoutlets()){
如果(o.equals(output.WIN)){
win++;
全部++;
}否则,如果(o等于(结果失败)){
丢失++;
全部++;
}否则{
draw++;
全部++;
}
}
}
DecimalFormat statFormat=新的DecimalFormat(“##.##”);
统计:团队获胜:“+statFormat.format(win*100/all)+”%,失败“+statFormat.format(lose*100/all)
+“%,绘图:”+statFormat.format(绘图*100/全部)+“%”;
}

我熟悉lambda表达式。我试图在网上寻找解决方案,但找不到流访问类字段字段的示例。如果你能给我一个解决方案,或者给我一个相关的教程,我会很高兴的。谢谢。

要访问
流中类的字段
,请使用
映射

games.stream().map(游戏->
game.getoutlets().stream().map(结果->{
//对每个结果都做些什么`
})
)
上面的代码假设
getoutcouts()
返回一个
列表
,当前版本的OP问题中没有指定该列表

请注意,您不能像希望的那样简单地递增
中的计数器,因为
中使用的所有变量必须是final或有效final。您必须深入研究
API,以了解如何以原始解决方案中的方式增加


提示:您希望执行类似的操作,这将利用。

groupingBy
适合这种情况:

Map<Outcome, Long> map = games.stream()
        .flatMap(game -> game.getOutcomes().stream())
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
要获得
all
count,您需要对map中的所有值求和

long all = map.values().stream()
    .mapToLong(Long::valueOf)
    .sum();

您可以对游戏进行流式处理,将其平面映射到结果,然后将其收集到计数图中:

Map<Outcome, Long> counts = games.stream()
        .map(Game::getOutcomes)
        .flatMap(Collection::stream)
        .collecting(Collectors.groupingBy(o -> o, Collectors.counting()));

long win = counts.getOrDefault(Outcome.WIN, 0L);
long lose = counts.getOrDefault(Outcome.LOSE, 0L);
long draw = counts.getOrDefault(Outcome.DRAW, 0L);
long all = games.stream()
        .mapToInt(g -> g.getOutcomes().size())
        .sum();
Map counts=games.stream()
.map(游戏::获取结果)
.flatMap(集合::流)
.collection(Collectors.groupingBy(o->o,Collectors.counting());
long win=counts.getOrDefault(output.win,0L);
长期损失=计数.getOrDefault(结果.lose,0L);
长绘图=counts.getOrDefault(output.draw,0L);
long all=games.stream()
.mapToInt(g->g.getoutcouts().size())
.sum();

为什么要使用流?不会更有效,因为您需要计算与您操作的对象没有直接关系的多个值。这也是我的第一个问题。我不可能只用一条管线就得到我需要的所有3个值,对吗?为什么要对离散值使用浮点数?如果只是为了浮点数学,你可以让文本浮点数。例如,
win*100f/all
谢谢你指出这一点!
Map<Outcome, Long> counts = games.stream()
        .map(Game::getOutcomes)
        .flatMap(Collection::stream)
        .collecting(Collectors.groupingBy(o -> o, Collectors.counting()));

long win = counts.getOrDefault(Outcome.WIN, 0L);
long lose = counts.getOrDefault(Outcome.LOSE, 0L);
long draw = counts.getOrDefault(Outcome.DRAW, 0L);
long all = games.stream()
        .mapToInt(g -> g.getOutcomes().size())
        .sum();