Каков наилучший способ перебора строк Java-строки? - PullRequest
49 голосов
/ 13 февраля 2012

В настоящее время я использую что-то вроде:

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

Я не очень рад этому методу, потому что он создает тяжелый массив (скажем, textContent может содержать книгу).

Есть ли лучшее решение для итерации по строкам String?

Ответы [ 9 ]

56 голосов
/ 13 февраля 2012

Вы можете использовать:

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

И использовать метод readLine():

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

}
19 голосов
/ 15 августа 2015

Чтобы добавить способ Java 8 к этому вопросу:

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

Конечно, вы также можете использовать System.lineSeparator() для разделения, если вы уверены, что файл идет с той же платформы, на которой работает vm.

Или даже лучше использовать потоковый API, еще более агрессивный с фильтром, картой и сбором:

String result = Arrays.stream(content.split(System.lineSeparator()))
                     .filter(/* filter for lines you are interested in*/)
                     .map(/*convert string*/)
                     .collect(Collectors.joining(";"));
6 голосов
/ 13 февраля 2012

Вы можете использовать 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.
}
5 голосов
/ 13 февраля 2012

Guava's Splitter работает хорошо.Тем более, что вы можете удалить пустые строки

Splitter splitter = Splitter.on(System.getProperty("line.separator"))
                            .trimResults()
                            .omitEmptyStrings();
for (String line : splitter.split(input)){
   // do work here
}
5 голосов
/ 13 февраля 2012

Scanner

А как насчет класса java.util.Scanner, добавленного в 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();
2 голосов
/ 09 февраля 2017

Вы можете на самом деле спорить 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
1 голос
/ 31 мая 2018

Я полагаю, что у вас есть лучший API, доступный с JDK / 11, где вы можете сделать то же самое с помощью API String.lines(), который возвращает поток строк, извлеченных из этой строки, разделенных разделителями строк.

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.
1 голос
/ 13 февраля 2012

Объединение java.io.StringReader и java.io.LineNumberReader

1 голос
/ 13 февраля 2012

использовать 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
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...