Dada uma string que não é muito longa, qual é a melhor maneira de lê-la linha por linha?
Eu sei que você pode fazer:
BufferedReader reader = new BufferedReader(new StringReader(<string>));
reader.readLine();
Outra maneira seria pegar a substring no eol:
final String eol = System.getProperty("line.separator");
output = output.substring(output.indexOf(eol + 1));
Alguma outra maneira talvez mais simples de fazer isso? Não tenho problemas com as abordagens acima, apenas interessado em saber se algum de vocês sabe algo que pode parecer mais simples e mais eficiente?
Respostas:
Você também pode usar o
split
método String:Isso fornece todas as linhas em uma matriz prática.
Eu não sei sobre o desempenho da divisão. Ele usa expressões regulares.
fonte
line.separator
e alguém a ler no windows usandoline.separator
, ela ainda será alterada. Isso não é um programador incompetente de fazer coisas estúpidas, é assim que as coisas (nem sempre) funcionam.Existe também
Scanner
. Você pode usá-lo exatamente comoBufferedReader
:Eu acho que essa é uma abordagem um pouco mais limpa que as duas sugeridas.
fonte
Como eu estava especialmente interessado no ângulo da eficiência, criei uma pequena classe de teste (abaixo). Resultado para 5.000.000 de linhas:
Como de costume, os horários exatos podem variar, mas a proporção é verdadeira, embora muitas vezes eu a execute.
Conclusão: os requisitos "mais simples" e "mais eficientes" do OP não podem ser satisfeitos simultaneamente, a
split
solução (em qualquer encarnação) é mais simples, mas aReader
implementação supera as demais.fonte
lines()
função retornando umaStream<String>
das linhas, que você pode coletar em uma lista, se desejar, ou processar o fluxo.Usando o Apache Commons IOUtils, você pode fazer isso muito bem via
Não está fazendo nada inteligente, mas é agradável e compacto. Ele também lida com fluxos, e você também pode obter um,
LineIterator
se preferir.fonte
IOUtils.readlines(Reader)
gera umIOException
. Mesmo que isso provavelmente nunca aconteça com um StringReader, você precisará capturá-lo ou declará-lo.Solução usando
Java 8
recursos comoStream API
eMethod references
ou
fonte
Desde o Java 11, existe um novo método
String.lines
:Uso:
fonte
Você pode usar a API do fluxo e um StringReader envolto em um BufferedReader que obteve uma saída de fluxo lines () no java 8:
Dá
Assim como no readLine do BufferedReader, os próprios caracteres de nova linha não são incluídos. Todos os tipos de separadores de nova linha são suportados (na mesma sequência mesmo).
fonte
Você também pode usar:
Se isso não funcionar, tente substituir
\n
por\r\n
.fonte
Ou use a nova cláusula try with resources combinada com o Scanner:
fonte
Você pode tentar a seguinte expressão regular:
Código:
Resultado:
fonte
A abordagem mais fácil e universal seria usar apenas o regex
Linebreak matcher
\R
que correspondeAny Unicode linebreak sequence
:@see https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Pattern.html
fonte