Quelle est la meilleure façon d'itérer sur les lignes D'une chaîne Java?
Actuellement, j'utilise quelque chose comme:
String[]lines = textContent.split(System.getProperty("line.separator"));
for(String tmpLine : lines){
//do something
}
Je ne suis pas très content de cette méthode car elle crée un tableau lourd (disons que {[1] } peut contenir un livre).
Est-il une meilleure solution pour itérer sur les lignes d'une String
?
9 réponses
, Vous pouvez utiliser :
BufferedReader bufReader = new BufferedReader(new StringReader(textContent));
Et utilisez la méthode readLine()
:
String line=null;
while( (line=bufReader.readLine()) != null )
{
}
Pour ajouter la méthode Java 8 à cette question:
Arrays.stream(content.split("\\r?\\n")).forEach(line -> /*do something */)
De curse vous pouvez également utiliser System.lineSeparator()
pour diviser si vous êtes sûr que le fichier vient de la même plate-forme que la vm s'exécute.
Ou encore mieux utiliser l'api stream encore plus agressiv avec filter, map et collect:
String result = Arrays.stream(content.split(System.lineSeparator()))
.filter(/* filter for lines you are interested in*/)
.map(/*convert string*/)
.collect(Collectors.joining(";"));
Vous pouvez utiliser String.indexOf () / chaîne.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.
}
Le séparateur De Goyave fonctionne bien. D'autant plus que vous pouvez supprimer les lignes vides
Splitter splitter = Splitter.on(System.getProperty("line.separator"))
.trimResults()
.omitEmptyStrings();
for (String line : splitter.split(input)){
// do work here
}
Scanner
Qu'en est-il du java.util.Scanner
classe ajoutée en Java 1.5?
En résumé:
Un scanner de texte simple qui peut analyser les types primitifs et les chaînes à l'aide d'expressions régulières.
Un Scanner décompose son entrée en jetons à l'aide d'un motif délimiteur, qui correspond par défaut aux espaces. Les jetons résultants peuvent alors être convertie en valeurs de différents types à l'aide des méthode.
Et de note pour votre scénario:
Le scanner peut également utiliser des délimiteurs autres que les espaces. Ce exemple lit plusieurs éléments dans une chaîne:
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();
, Vous pouvez réellement se quereller Scanner
pour vous permettre d'utiliser une normale for
boucle:
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);
}
}
}
Nous Donne:
$ javac IterateLines.java && java IterateLines
foo bar
baz
Je crois que vous avez une meilleure API disponible avec JDK / 11 où vous pouvez faire la même chose en utilisant le String.lines()
API qui renvoie le flux de chaînes extraites de cette chaîne partitionnée par les terminateurs de ligne.
public Stream<String> lines()
L'Utilisation de la même chose pourrait être :-
Stream<String> linesFromString = textContent.lines();
linesFromString.forEach(l -> {
//do sth
});
Note importante de L'API :-
@implNote This method provides better performance than
split("\R") by supplying elements lazily and
by faster search of new line terminators.
Utilisez BufferedReader avec l'argument StringReader. BufferedReader a une méthode readLine () afin que vous puissiez lire votre chaîne ligne par ligne.
StringReader reader = new StringReader(myBigTextString);
BufferedReader br = new BufferedReader(reader);
String line;
while((line=br.readLine())!=null)
{
//do what you want
}