What is the best way to iterate over the lines of a Java String?

Currently I'm using something like :

String[]lines = textContent.split(System.getProperty("line.separator"));
for(String tmpLine : lines){
   //do something
}

I'm not very glad of this method because it create an heavy array (let say textContent can contain a book).

Is there any better solution to iterate over the lines of a String?


You could use :

BufferedReader bufReader = new BufferedReader(new StringReader(textContent));

And use the readLine() method :

String line=null;
while( (line=bufReader.readLine()) != null )
{

}

To add the Java 8 way to this question:

Arrays.stream(content.split("\\r?\\n")).forEach(line -> /*do something */)

Of curse you can also use System.lineSeparator()to split if you are sure that the file is comming from the same plattform as the vm runs on.

Or even better use the stream api even more agressiv with filter, map and collect:

String result = Arrays.stream(content.split(System.lineSeparator()))
                     .filter(/* filter for lines you are interested in*/)
                     .map(/*convert string*/)
                     .collect(Collectors.joining(";"));

I believe you have a better API available starting with Java-11 where you can do the same using the String.lines() API which returns the stream of strings extracted from this string partitioned by line terminators.

public Stream<String> lines()

Usage of the same could be:-

Stream<String> linesFromString = textContent.lines();
linesFromString.forEach(l -> {  //do sth });

Important API Note :-

@implNote This method provides better performance than
          split("\R") by supplying elements lazily and
          by faster search of new line terminators.

You could use 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.
}