簡體   English   中英

如何將計數器插入Stream <String> .forEach()?

[英]How to insert a counter into a Stream<String> .forEach()?

FileWriter writer = new FileWriter(output_file);
    int i = 0;

    try (Stream<String> lines = Files.lines(Paths.get(input_file))) {
        lines.forEach(line -> {
            try {
                writer.write(i + " # " + line + System.lineSeparator());
            } catch (Exception e) {
                e.printStackTrace();
            }   
        }
                    );
        writer.close();
    }

我需要用行號寫行,所以我試着在.forEach()中添加一個計數器,但是我無法讓它工作。 我只是不知道把i ++放在哪里; 進入代碼,隨機搞砸到目前為止沒有幫助。

您可以使用AtomicInteger作為可變的final計數器。

public void test() throws IOException {
    // Make sure the writer closes.
    try (FileWriter writer = new FileWriter("OutFile.txt") ) {
        // Use AtomicInteger as a mutable line count.
        final AtomicInteger count = new AtomicInteger();
        // Make sure the stream closes.
        try (Stream<String> lines = Files.lines(Paths.get("InFile.txt"))) {
            lines.forEach(line -> {
                        try {
                            // Annotate with line number.
                            writer.write(count.incrementAndGet() + " # " + line + System.lineSeparator());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
            );
        }
    }
}

這是一個很好的例子,你應該使用一個好的老式for循環。 雖然Files.lines()專門提供順序流,但是流可以不按順序生成和處理,因此插入計數器並依賴它們的順序是一個相當不好的習慣。 如果您仍然真的想要這樣做,請記住,在任何可以使用lambda的地方,您仍然可以使用完整的匿名類。 匿名類是普通類,因此可以具有狀態。

所以在你的例子中你可以這樣做:

FileWriter writer = new FileWriter(output_file);

try (Stream<String> lines = Files.lines(Paths.get(input_file))) {
    lines.forEach(new Consumer<String>() {
        int i = 0;
        void accept(String line) {
            try {
                writer.write((i++) + " # " + line + System.lineSeparator());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    writer.close();
}

Java doc中所述

使用但未在lambda表達式中聲明的任何局部變量,形式參數或異常參數必須聲明為final或者是有效的final(§4.12.4),否則在嘗試使用時會發生編譯時錯誤。

這意味着您的變量必須是最終的或有效的最終變量。 您想在forEach添加一個計數器,為此您可以使用OldCurumudgeon建議的AtomicInteger ,這是IMO的首選方法。

我相信你也可以使用只有一個值為0的數組,你可以用它作為計數器。 檢查並告訴我以下示例是否適合您:

public void test() throws IOException {
    FileWriter writer = new FileWriter("OutFile.txt");
    final int[] count = {0};

    try (Stream<String> lines = Files.lines(Paths.get("InFile.txt"))) {
        lines.forEach(line -> {
            try {
                count[0]++;
                writer.write(count[0] + " # " + line + System.lineSeparator());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        );
        writer.close();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM