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?

44
demandé sur alain.janinm 2012-02-13 15:06:38

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 )
{

}
48
répondu Guillaume Polet 2012-02-13 16:13:07

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(";"));
14
répondu leo 2017-08-23 10:43:32

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.
}
6
répondu Brendan 2012-02-13 11:12:17

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
}
5
répondu John B 2016-04-16 12:36:48

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();
5
répondu Alex 2018-05-21 07:25:48

, 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
2
répondu Andy Balaam 2017-06-09 13:30:11

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.
2
répondu nullpointer 2018-05-31 19:34:58

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
    }
1
répondu shift66 2012-02-13 11:15:13

Combiner java.io.StringReader et java.io.LineNumberReader

1
répondu david a. 2012-02-13 11:18:26