繁体   English   中英

有人可以简要向我解释IntStream发生了什么吗?

[英]Can somebody please briefly explain to me what's happening with the IntStream?

我在网上查找了多个示例,但似乎无法理解这里发生的事情。 当程序打印出当前的球员和比分时,对我来说这些存储位置并不明显。 我是一个初学者,被告知我分析这段代码以帮助“更好地理解”我们当前的课堂项目。

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
import java.util.stream.IntStream;

public interface PigDice {
    public static void main(String... arguments) {
        final int maxScore = 100;
        final int playerCount = 2;
        final String[] yesses = { "y", "Y", "" };

        final Scanner scanner = new Scanner(System.in);
        final Random random = new Random();

        final int[] safeScore = new int[2];
        final int[] score = new int[2];

        IntStream.iterate(0, player -> (player + 1) % playerCount).map(player -> {
            boolean isRolling = true;
            while (isRolling) {
                System.out.printf("Player %d: (%d, %d) Rolling? (y/n) ", player, safeScore[player], score[player]);
            isRolling = safeScore[player] + score[player] < maxScore
                    && Arrays.asList(yesses).contains(scanner.nextLine());
                if (isRolling) {
                    final int rolled = random.nextInt(6) + 1;
                    System.out.printf("Rolled %d\n", rolled);
                    if (rolled == 1) {
                        System.out.printf("Bust! You lose %d but keep %d\n\n", score[player], safeScore[player]);
                        return -1;
                    } else {
                        score[player] += rolled;
                    }
                } else {
                    safeScore[player] += score[player];
                    if (safeScore[player] >= maxScore) {
                        return player;
                    }
                    System.out.printf("Sticking with %d\n\n", safeScore[player]);
                }
            }
            score[player] = 0;
            return -1;
        }).filter(player -> player > -1).findFirst().ifPresent(
                player -> System.out.printf("\n\nPlayer %d wins with a score of %d", player, safeScore[player]));
    }
}

为了理解这段代码的作用,我首先要应用几个关键的重构:

  1. main()的所有局部变量提升为PigDice类的静态变量。

  2. 将传递给map()的大型多行lambda提取到PigDice类的静态方法中。 调用此方法turn()

     static int turn(int player) { ... } 

现在,流管道如下所示:

    IntStream.iterate(0, player -> (player + 1) % playerCount)
             .map(PigDice::turn)
             .filter(player -> player > -1)
             .findFirst()
             .ifPresent(
                player ->
                    System.out.printf("\n\nPlayer %d wins with a score of %d",
                        player, safeScore[player]));

IntStream.iterate()方法生成一个以提供的初始值开头的int值流,在这种情况下,该初始值为零。 后续值由lambda表达式计算。 在这里,该表达式加1并使用playerCount计算余数,在本示例中为2。 结果是一个值流0、1、0、1、0、1,...,表示轮到其的玩家编号。

map()阶段将这些值中的每个传递给turn()方法,该方法执行所有游戏逻辑。 但是,如果您简化此逻辑,则如果没有获胜者,则基本上返回-1;如果获胜者,则返回其输入参数(当前玩家编号)。 如果玩家0获胜,则流-1,-1,-1,-1,... 0(如果玩家1获胜,则最后一个值为1)。

map()的结果流只是故事的一部分。 在实际的游戏逻辑由游戏状态,其被保持在所捕捉的变量副作用操作scannerrandomscore ,和safeScore

filter()阶段仅通过大于-1的值,因此在游戏进行过程中它将丢弃所有这些前-1的值,仅在玩家获胜后才产生一个值。

findFirst()阶段获取第一个元素,然后终止流。 这就是游戏最终终止的原因。

现在, findFirst()返回一个OptionalInt ,其中包含获胜玩家的号码。 通常,它可以为空,但是在这种情况下,它永远不会为空,因为iterate()会生成无限流。 由于永远不会为空,因此始终执行ifPresent()的lambda表达式,并将其传递给获胜玩家的号码; 这会打印出最终的游戏结果。

基本上就是这样。

请注意,正如我和其他人在评论中指出的那样,这里有一些不良的代码味道和反模式,以及一些错误。 我强烈建议不要将其用作良好的lambda和流编码实践的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM