逐行读取string

给定一个不太长的string,最好的方法是逐行读取它?

我知道你可以这样做:

BufferedReader reader = new BufferedReader(new StringReader(<string>)); reader.readLine(); 

另一种方法是采取在EOL的子string:

 final String eol = System.getProperty("line.separator"); output = output.substring(output.indexOf(eol + 1)); 

任何其他更简单的方法呢? 我对上述方法没有任何问题,只是有兴趣知道是否有人知道可能看起来更简单,更有效率的东西?

你也可以使用String的split方法:

 String[] lines = myString.split(System.getProperty("line.separator")); 

这给你一个方便的数组中的所有行。

我不知道分裂的performance。 它使用正则expression式。

还有Scanner 。 你可以像BufferedReader一样使用它:

 Scanner scanner = new Scanner(myString); while (scanner.hasNextLine()) { String line = scanner.nextLine(); // process the line } scanner.close(); 

我认为这是两个build议的一个更清洁的方法。

由于我对效率angular度特别感兴趣,所以我创build了一个小testing课(下面)。 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 

像往常一样,确切的时间可能会有所不同,但是这个比例是正确的,但是我经常运行它。

结论:OP的“更简单”和“更高效”的要求不能同时满足, split解决scheme(两种forms)都比较简单,但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(); } } 

使用Apache Commons IOUtils,你可以通过很好的方式做到这一点

 List<String> lines = IOUtils.readLines(new StringReader(string)); 

它没有做任何聪明的事情,但它很好,很紧凑。 它也会处理stream,如果你愿意,你也可以得到一个LineIterator

使用Java 8function(如Stream APIMethod references解决scheme

 new BufferedReader(new StringReader(myString)) .lines().forEach(System.out::println); 

要么

 public void someMethod(String myLongString) { new BufferedReader(new StringReader(myLongString)) .lines().forEach(this::parseString); } private void parseString(String data) { //do something } 

你也可以使用:

 String[] lines = someString.split("\n"); 

如果这不起作用,请用\r\nreplace\r\n

您可以使用streamapi和一个包装在BufferedReader中的StringReader,它在java 8中获得了一个lines()stream输出:

 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) ); } } 

 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 

就像在BufferedReader的readLine中一样,换行符本身也不包含在内。 支持各种换行符分隔符(甚至在同一个string中)。

或者使用与Scanner结合的资源子句的新尝试:

  try (Scanner scanner = new Scanner(value)) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); // process the line } } 

番石榴:

 ImmutableList<String> lines = CharSource.wrap(str).readLines(); 

你可以尝试下面的正则expression式:

 \r?\n 

码:

 String input = "\nab\n\n \n\ncd\nef\n\n\n\n\n"; String[] lines = input.split("\\r?\\n", -1); int n = 1; for(String line : lines) { System.out.printf("\tLine %02d \"%s\"%n", n++, line); } 

输出:

 Line 01 "" Line 02 "ab" Line 03 "" Line 04 " " Line 05 "" Line 06 "cd" Line 07 "ef" Line 08 "" Line 09 "" Line 10 "" Line 11 "" Line 12 ""