[英]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]));
}
}
为了理解这段代码的作用,我首先要应用几个关键的重构:
将main()
的所有局部变量提升为PigDice
类的静态变量。
将传递给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()
的结果流只是故事的一部分。 在实际的游戏逻辑由游戏状态,其被保持在所捕捉的变量副作用操作scanner
, random
, score
,和safeScore
。
filter()
阶段仅通过大于-1的值,因此在游戏进行过程中它将丢弃所有这些前-1的值,仅在玩家获胜后才产生一个值。
findFirst()
阶段获取第一个元素,然后终止流。 这就是游戏最终终止的原因。
现在, findFirst()
返回一个OptionalInt
,其中包含获胜玩家的号码。 通常,它可以为空,但是在这种情况下,它永远不会为空,因为iterate()
会生成无限流。 由于永远不会为空,因此始终执行ifPresent()
的lambda表达式,并将其传递给获胜玩家的号码; 这会打印出最终的游戏结果。
基本上就是这样。
请注意,正如我和其他人在评论中指出的那样,这里有一些不良的代码味道和反模式,以及一些错误。 我强烈建议不要将其用作良好的lambda和流编码实践的示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.