遍历Java String行的最佳方法是什么?
目前,我正在使用类似:
String[]lines = textContent.split(System.getProperty("line.separator"));
for(String tmpLine : lines){
//do something
}
我对这种方法不太满意,因为它会创建大量数组(比如说String可以包含一本书)。
有没有更好的解决方案来迭代String的行?
alain.janinm asked 2020-01-28T17:22:54Z
9个解决方案
56 votes
您可以使用:
BufferedReader bufReader = new BufferedReader(new StringReader(textContent));
并使用readLine()方法:
String line=null;
while( (line=bufReader.readLine()) != null )
{
}
Guillaume Polet answered 2020-01-28T17:23:11Z
19 votes
要向该问题添加Java 8方法:
Arrays.stream(content.split("\\r?\\n")).forEach(line -> /*do something */)
当然,如果您确定文件与vm运行所在的平台相同,还可以使用System.lineSeparator()进行拆分。
甚至更好地使用带有过滤,映射和收集功能的流api甚至更多的agressiv:
String result = Arrays.stream(content.split(System.lineSeparator()))
.filter(/* filter for lines you are interested in*/)
.map(/*convert string*/)
.collect(Collectors.joining(";"));
leo answered 2020-01-28T17:23:41Z
6 votes
您可以使用String.indexOf()/ String.substring()
String separator = System.getProperty("line.separator");
int index = textContent.indexOf(separator);
while (index > 0)
{
int nextIndex = textContent.indexOf(separator, index + separator.length());
String line = textContent.substring(index + separator.length(), nextIndex);
// do something with line.
}
Brendan answered 2020-01-28T17:24:00Z
5 votes
番石榴的分离器效果很好。 特别是因为您可以删除空白行
Splitter splitter = Splitter.on(System.getProperty("line.separator"))
.trimResults()
.omitEmptyStrings();
for (String line : splitter.split(input)){
// do work here
}
John B answered 2020-01-28T17:24:21Z
5 votes
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();
Java 1.5中添加的String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();类怎么办?
综上所述:
一个简单的文本扫描器,可以解析原始类型和字符串 使用正则表达式。
扫描程序会使用定界符模式将其输入分为令牌, 默认情况下,它与空格匹配。 然后,生成的令牌可能是 使用各种next转换为不同类型的值 方法。
并请注意您的情况:
扫描仪还可以使用空格以外的定界符。 这个 示例从字符串中读取多个项目:
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();
Alex answered 2020-01-28T17:25:12Z
2 votes
您实际上可以纠缠Scanner以允许您使用正常的for循环:
import java.util.Scanner;
public class IterateLines {
public static void main(String[] args) {
Iterable sc = () ->
new Scanner("foo bar\nbaz\n").useDelimiter("\n");
for (String line: sc) {
System.out.println(line);
}
}
}
给我们:
$ javac IterateLines.java && java IterateLines
foo bar
baz
Andy Balaam answered 2020-01-28T17:25:37Z
2 votes
我相信JDK / 11提供了更好的API,您可以使用String.lines() API来执行相同的操作,该API返回从由行终止符划分的该字符串中提取的字符串流。
public Stream lines()
相同的用法可能是:-
Stream linesFromString = textContent.lines();
linesFromString.forEach(l -> {
//do sth
});
重要的API注意事项:-
@implNote This method provides better performance than
split("\R") by supplying elements lazily and
by faster search of new line terminators.
Naman answered 2020-01-28T17:26:06Z
1 votes
将BufferedReader与StringReader参数一起使用。 BufferedReader具有readLine()方法,因此您可以逐行读取字符串。
StringReader reader = new StringReader(myBigTextString);
BufferedReader br = new BufferedReader(reader);
String line;
while((line=br.readLine())!=null)
{
//do what you want
}
shift66 answered 2020-01-28T17:26:27Z
1 votes
结合java.io.StringReader和java.io.LineNumberReader
david a. answered 2020-01-28T17:26:47Z