目前我使用的是:
String[]lines = textContent.split(System.getProperty("line.separator"));
for(String tmpLine : lines){
//do something
}
我对这种方法不是很满意,因为它创建了一个沉重的数组(假设textContent
可以包含一本书)。
是否有更好的解决方案来迭代String
的行?
答案 0 :(得分:56)
您可以使用:
BufferedReader bufReader = new BufferedReader(new StringReader(textContent));
并使用readLine()
方法:
String line=null;
while( (line=bufReader.readLine()) != null )
{
}
答案 1 :(得分:19)
将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(";"));
答案 2 :(得分:6)
您可以使用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.
}
答案 3 :(得分:5)
Scanner
Java 1.5中添加的java.util.Scanner
类怎么样?
总结:
一个简单的文本扫描程序,可以解析基本类型和字符串 使用正则表达式。
扫描仪使用分隔符模式将其输入分解为标记, 默认情况下匹配空格。然后可以得到所产生的令牌 使用各种下一个转换为不同类型的值 方法
并注意您的方案:
扫描仪还可以使用空格以外的分隔符。这个 示例从字符串中读取几个项目:
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();
答案 4 :(得分:5)
Guava的Splitter效果很好。特别是你可以删除空行
Splitter splitter = Splitter.on(System.getProperty("line.separator"))
.trimResults()
.omitEmptyStrings();
for (String line : splitter.split(input)){
// do work here
}
答案 5 :(得分:2)
您实际上可以与Scanner
争吵,以允许您使用正常的for
循环:
import java.util.Scanner;
public class IterateLines {
public static void main(String[] args) {
Iterable<String> 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
答案 6 :(得分:1)
将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
}
答案 7 :(得分:1)
合并java.io.StringReader
和java.io.LineNumberReader
答案 8 :(得分:1)
我相信您可以使用JDK / 11获得更好的API,您可以使用 String.lines()
API执行相同操作,该API返回从此字符串中提取的字符串流,这些字符串由行终止符分区
public Stream<String> lines()
相同的用法可能是: -
Stream<String> 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.
答案 9 :(得分:1)
如果您使用的是Java 1.8(或Android),请尝试以下操作:
new BufferedReader(new StringReader(str)).lines().forEachOrdered((line) -> {
// process each line as you like
});
该流是延迟填充的,即在终端流操作期间只读发生。
这意味着它的运行速度比其他解决方案要快,其他解决方案在迭代开始之前先生成大量的Strings。
如果您使用的是Java 11或更高版本,那么@Naman推荐String#lines()方法的答案也更加简洁,快速,请参阅https://stackoverflow.com/a/50631579/215266