计算java中字符串中的行数 - BufferedReader行为

时间:2015-07-03 16:51:41

标签: java bufferedreader java-io

我使用函数 countLines 来计算字符串中的行数。它使用StringReader和BufferedReader。但是在我的示例中,我得到的结果与我预期的字符串 test 不同。有人可以验证这种情况,并判断BufferedReader是否按预期运行。

package test;

import java.io.BufferedReader;
import java.io.StringReader;

public class LineCountTest {

    private static final String test = "This is a\ntest string\n\n\n";
    private static final String test2 = "This is a\ntest string\n\n\n ";

    public static void main(String[] args) {
        System.out.println("Line count: " + countLines(test));
        System.out.println("Line count: " + countLines(test2));
    }

    private static int countLines(String s) {
        try (
                StringReader sr = new StringReader(s);
                BufferedReader br = new BufferedReader(sr)
        ) {
            int count = 0;
            for (String line = br.readLine(); line != null; line = br.readLine()) {
                count++;
            }
            return count;
        } catch (Exception e) {
            return -1;
        }
    }

}

我希望countLines在两种情况下都返回 5 ,但它会为第一个字符串返回 4

背景:我实际上需要 line 的值来填充一个字符串数组,并期望最后一个元素是空字符串。

编辑:我已经知道了

String[] lines = s.split("\n", -1);
int count = lines.length;

会给我正确/预期的行数。我只询问性能原因,如果有人可以判断BufferedReader是否正常运行。

4 个答案:

答案 0 :(得分:1)

选中code

class LineCountTest
{
    private static final String test = "This is a\ntest string\n\n\n";
    private static final String test2 = "This is a\ntest string\n\n\n ";

    public static void main(String[] args) {
        System.out.println("Line count: " + countLines(test));
        System.out.println("Line count: " + countLines(test2));
    }

    private static int countLines(String s) {
        return (s + " ").split("\r?\n").length;
    }
}

这将解决您的问题。

此代码按\r\n\n拆分字符串并返回行数。

添加额外的空格,以便即使它是空的,也会计算最后一行。

BufferedReader表现正常。

条件line != null导致问题。

在字符串test中,在\n后面有null读取为BufferedReader#readLine(),这就是为什么循环终止,输出为4

在字符串test2中,在最后一个\n之后有一个空格,它允许另一次迭代,输出为5

答案 1 :(得分:0)

因此,当您以\n结尾或非空时,您会发现最后一行被识别出来。

出于您的目的,人们可以使用:

String[] lines = "This is a\ntest string\n\n\n".split("\r?\n", 5);

这确保了数组将具有5个元素。虽然正则表达式分裂有点慢。

答案 2 :(得分:0)

如果你在第一个字符串中添加一个额外的空格。

private static final String test = "This is a\ntest string\n\n\n ";

你会得到同样的数。 主要原因是for循环:

for (String line = br.readLine(); line != null; line = br.readLine()) 
{
        count++;
}

for循环“line = br.readLine()”的第三个参数只返回一个字符串,如果“\ n”之后有任何其他字符串可用。在你的第一个字符串中没有其他字符,但在你的第二个字符串中你添加了一个空格,现在这个空间被认为是一个新的字符串。这就是为什么你得到4和5计数。

答案 3 :(得分:0)

如果您使用Java 8,那么:

long lines = stringWithNewlines.chars().filter(x -> x == '\n').count() + 1;

(如果裁剪字符串,最后+ 1将计算最后一行)