簡體   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