计算 java 中字符串中的行数 - BufferedReader 行为
Count number of lines in a string in java - BufferedReader behavior
我正在使用函数 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 在这两种情况下都达到 return 5,但是 returns 4第一个字符串。
背景:我实际上需要 line 的值来填充字符串数组,并希望最后一个元素是空字符串。
编辑:我已经知道
String[] lines = s.split("\n", -1);
int count = lines.length;
会给我 correct/expected 行数。我只询问性能原因,以及是否有人可以判断 BufferedReader 的行为是否正确。
所以你发现最后一行以 \n
结尾或非空时被识别。
出于您的目的,您可以使用:
String[] lines = "This is a\ntest string\n\n\n".split("\r?\n", 5);
这确保数组将有 5 个元素。正则表达式拆分虽然有点慢。
检查此 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
和 return 行数拆分字符串。
添加了额外的空格space,这样即使最后一行为空,也会计算在内。
BufferedReader
运行正常。
条件 line != null
导致了问题。
在字符串test
中,最后一个\n
后有nothing,被[=18=读为null
] 这就是循环终止且输出为 4
.
的原因
在字符串test2
中,在最后一个\n
之后有一个空白space,这样就可以再次迭代,输出为5
.
如果您在第一个字符串中添加额外的 space。
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()"只有return一个字符串,如果在“\n”之后有可用的任何其他字符串。在你的第一个字符串中没有其他字符,但在你的第二个字符串中你添加了一个 space 并且这个 space 现在被视为一个新字符串。这就是为什么你得到 4 和 5 计数的原因。
如果您使用 Java 8 那么:
long lines = stringWithNewlines.chars().filter(x -> x == '\n').count() + 1;
(最后+1是如果字符串被裁剪算到最后一行)
我正在使用函数 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 在这两种情况下都达到 return 5,但是 returns 4第一个字符串。
背景:我实际上需要 line 的值来填充字符串数组,并希望最后一个元素是空字符串。
编辑:我已经知道
String[] lines = s.split("\n", -1);
int count = lines.length;
会给我 correct/expected 行数。我只询问性能原因,以及是否有人可以判断 BufferedReader 的行为是否正确。
所以你发现最后一行以 \n
结尾或非空时被识别。
出于您的目的,您可以使用:
String[] lines = "This is a\ntest string\n\n\n".split("\r?\n", 5);
这确保数组将有 5 个元素。正则表达式拆分虽然有点慢。
检查此 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
和 return 行数拆分字符串。
添加了额外的空格space,这样即使最后一行为空,也会计算在内。
BufferedReader
运行正常。
条件 line != null
导致了问题。
在字符串test
中,最后一个\n
后有nothing,被[=18=读为null
] 这就是循环终止且输出为 4
.
在字符串test2
中,在最后一个\n
之后有一个空白space,这样就可以再次迭代,输出为5
.
如果您在第一个字符串中添加额外的 space。
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()"只有return一个字符串,如果在“\n”之后有可用的任何其他字符串。在你的第一个字符串中没有其他字符,但在你的第二个字符串中你添加了一个 space 并且这个 space 现在被视为一个新字符串。这就是为什么你得到 4 和 5 计数的原因。
如果您使用 Java 8 那么:
long lines = stringWithNewlines.chars().filter(x -> x == '\n').count() + 1;
(最后+1是如果字符串被裁剪算到最后一行)