给定一个不太长的字符串,逐行读取它的最佳方法是什么?
我知道你可以这样做:
BufferedReader reader = new BufferedReader(new StringReader(<string>));
reader.readLine();
Run Code Online (Sandbox Code Playgroud)
另一种方法是在eol上获取子字符串:
final String eol = System.getProperty("line.separator");
output = output.substring(output.indexOf(eol + 1));
Run Code Online (Sandbox Code Playgroud)
这样做还有其他更简单的方法吗?我对上述方法没有任何问题,只想知道你们中是否有人知道看起来更简单,更有效的东西?
not*_*oop 193
还有Scanner.您可以像以下一样使用它BufferedReader:
Scanner scanner = new Scanner(myString);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// process the line
}
scanner.close();
Run Code Online (Sandbox Code Playgroud)
我认为这对于两个建议的方法都是一种更清洁的方法.
ftl*_*ftl 126
您还可以使用splitString 的方法:
String[] lines = myString.split(System.getProperty("line.separator"));
Run Code Online (Sandbox Code Playgroud)
这为您提供了方便的数组中的所有行.
我不知道拆分的表现.它使用正则表达式.
Are*_*end 39
由于我对效率角度特别感兴趣,我创建了一个小测试类(如下).5,000,000行的结果:
Comparing line breaking performance of different solutions
Testing 5000000 lines
Split (all): 14665 ms
Split (CR only): 3752 ms
Scanner: 10005
Reader: 2060
Run Code Online (Sandbox Code Playgroud)
像往常一样,确切的时间可能会有所不同,但这个比例是正确的,但是我经常运行它.
结论:OP的"更简单"和"更有效"的要求不能同时满足,split解决方案(在任何一个化身中)都比较简单,但Reader实现方式比其他人更容易实现.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* Test class for splitting a string into lines at linebreaks
*/
public class LineBreakTest {
/** Main method: pass in desired line count as first parameter (default = 10000). */
public static void main(String[] args) {
int lineCount = args.length == 0 ? 10000 : Integer.parseInt(args[0]);
System.out.println("Comparing line breaking performance of different solutions");
System.out.printf("Testing %d lines%n", lineCount);
String text = createText(lineCount);
testSplitAllPlatforms(text);
testSplitWindowsOnly(text);
testScanner(text);
testReader(text);
}
private static void testSplitAllPlatforms(String text) {
long start = System.currentTimeMillis();
text.split("\n\r|\r");
System.out.printf("Split (regexp): %d%n", System.currentTimeMillis() - start);
}
private static void testSplitWindowsOnly(String text) {
long start = System.currentTimeMillis();
text.split("\n");
System.out.printf("Split (CR only): %d%n", System.currentTimeMillis() - start);
}
private static void testScanner(String text) {
long start = System.currentTimeMillis();
List<String> result = new ArrayList<>();
try (Scanner scanner = new Scanner(text)) {
while (scanner.hasNextLine()) {
result.add(scanner.nextLine());
}
}
System.out.printf("Scanner: %d%n", System.currentTimeMillis() - start);
}
private static void testReader(String text) {
long start = System.currentTimeMillis();
List<String> result = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new StringReader(text))) {
String line = reader.readLine();
while (line != null) {
result.add(line);
line = reader.readLine();
}
} catch (IOException exc) {
// quit
}
System.out.printf("Reader: %d%n", System.currentTimeMillis() - start);
}
private static String createText(int lineCount) {
StringBuilder result = new StringBuilder();
StringBuilder lineBuilder = new StringBuilder();
for (int i = 0; i < 20; i++) {
lineBuilder.append("word ");
}
String line = lineBuilder.toString();
for (int i = 0; i < lineCount; i++) {
result.append(line);
result.append("\n");
}
return result.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*new 22
使用Apache Commons IOUtils,你可以很好地通过
List<String> lines = IOUtils.readLines(new StringReader(string));
Run Code Online (Sandbox Code Playgroud)
它没有做任何聪明的事情,但它很好而且紧凑.它也会处理流,LineIterator如果您愿意,也可以获得.
Bat*_*aev 14
使用和Java 8等功能的解决方案Stream APIMethod references
new BufferedReader(new StringReader(myString))
.lines().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
要么
public void someMethod(String myLongString) {
new BufferedReader(new StringReader(myLongString))
.lines().forEach(this::parseString);
}
private void parseString(String data) {
//do something
}
Run Code Online (Sandbox Code Playgroud)
从Java 11开始,有一种新方法String.lines:
/**
* Returns a stream of lines extracted from this string,
* separated by line terminators.
* ...
*/
public Stream<String> lines() { ... }
Run Code Online (Sandbox Code Playgroud)
用法:
"line1\nline2\nlines3"
.lines()
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)
您可以使用流api和包裹在BufferedReader中的StringReader来获取Java 8中的lines()流输出:
import java.util.stream.*;
import java.io.*;
class test {
public static void main(String... a) {
String s = "this is a \nmultiline\rstring\r\nusing different newline styles";
new BufferedReader(new StringReader(s)).lines().forEach(
(line) -> System.out.println("one line of the string: " + line)
);
}
}
Run Code Online (Sandbox Code Playgroud)
给
one line of the string: this is a
one line of the string: multiline
one line of the string: string
one line of the string: using different newline styles
Run Code Online (Sandbox Code Playgroud)
就像在BufferedReader的readLine中一样,不包含换行符。支持各种换行符(甚至在同一字符串中)。
您还可以使用:
String[] lines = someString.split("\n");
Run Code Online (Sandbox Code Playgroud)
如果不行请尝试更换\n用\r\n.
小智 5
或者使用新的 try with resources 子句结合 Scanner:
try (Scanner scanner = new Scanner(value)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// process the line
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
273278 次 |
| 最近记录: |