Sobre os seus métodos LerTexto
e LerTexto2
: para que ter 2 métodos que fazem a mesma coisa? Repare que a única coisa que muda é o nome do arquivo, todo o resto é igual. Então seria mais simples ter um único método que recebe como parâmetro o nome do arquivo.
Outro ponto é que não parece fazer sentido a mesma instância ter a contagem de 2 arquivos. Se quer usar compareTo
, imagino que a ideia seja comparar um arquivo com outro, levando em conta a quantidade de palavras. Então você teria que ter uma classe que representa a contagem de um único arquivo, e duas ou mais instâncias desta classe, cada uma lendo de um arquivo (mas o método para ler é um só). Mais ou menos isso:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
// classe que conta as palavras de um arquivo
public class ContadorDePalavras implements Comparable<ContadorDePalavras> {
private int qtdPalavras;
private String nomeArquivo;
public int getQtdPalavras() {
return qtdPalavras;
}
public String getNomeArquivo() {
return nomeArquivo;
}
// construtor recebe um nome de arquivo e conta as palavras dele
public ContadorDePalavras(String nomeArquivo) throws IOException {
this.nomeArquivo = nomeArquivo;
this.qtdPalavras = 0;
try (BufferedReader reader = new BufferedReader(new FileReader(nomeArquivo))) {
String linha;
while ((linha = reader.readLine()) != null) {
for (String s : linha.split("\\s+")) {
if (!s.isEmpty())
this.qtdPalavras++;
}
}
}
}
@Override
public int compareTo(ContadorDePalavras o) {
return Integer.compare(this.qtdPalavras, o.qtdPalavras);
}
}
Mudei o nome da classe para algo que faça um pouco mais de sentido, de acordo com a função dela. Pode parecer um detalhe besta, mas dar nomes melhores ajuda a programar melhor.
Eu não criei um setter para a quantidade de palavras porque não faz sentido. A quantidade de palavras é obtida somente a partir da leitura do arquivo, então não há motivo para poder alterá-la diretamente (no seu código, imagine que eu li um arquivo com 1000 palavras, e depois eu chamo setContPalavrasArquivo(10)
, a contagem ficaria errada). O mesmo vale para o nome do arquivo, faz sentido mudá-lo depois que eu já li? Enfim, só crie setters (e getters) se realmente fizer sentido.
Eu mudei o algoritmo de contagem. Como o outro código parece ter funcionado, estou assumindo que as palavras são “qualquer coisa separada por espaços”. Então eu uso split
para separar cada linha por espaços, e verifico se os resultados não têm strings vazias (isso acontece se a linha começa ou termina com espaços).
E repare que eu já fiz a leitura do arquivo no construtor, pois se a classe representa a contagem de palavras de um arquivo, só faz sentido ela existir se eu já tiver a contagem feita (claro que em sistemas reais isso dependeria dos requisitos, mas neste caso eu acho que faz mais sentido assim).
Também uso um bloco try-with-resources (funciona a partir do Java 7), que já fecha o arquivo ao final. Eu não estou capturando as exceções com um catch
, e em vez disso estou deixando a exceção estourar, afinal, se der erro na leitura do arquivo, eu não terei a contagem de palavras, então nesse caso nem faz sentido deixar o construtor criar a instância. Só faz sentido existir um ContadorDePalavras
se eu conseguir ler o arquivo até o final - se deu algum erro, eu deixei ele ser lançado e quem tentou criá-lo que faça o catch
, algo assim:
// no main
try {
// tento ler o arquivo e contar as palavras
ContadorDePalavras c1 = new ContadorDePalavras("arquivo.txt");
System.out.printf("Arquivo %s tem %d palavras", c1.getNomeArquivo(), c1.getQtdPalavras());
} catch (IOException e) { // se deu erro, não faz sentido criar o contador, mostra a mensagem de erro
System.out.println("Erro ao ler arquivo: " + e.getMessage());
}
E no compareTo
eu usei um método já pronto (Integer.compare
), que faz o mesmo que você estava fazendo manualmente.
Agora você pode criar sua lista de contadores de palavras e ordená-la de acordo com a quantidade de palavras:
// try-catch omitido
List<ContadorDePalavras> contadores = new ArrayList<>();
contadores.add(new ContadorDePalavras("arquivo.txt"));
contadores.add(new ContadorDePalavras("outro_arquivo.txt"));
contadores.add(new ContadorDePalavras("mais_outro_arquivo.txt"));
Collections.sort(contadores); // ordenar pela quantidade de palavras
for (ContadorDePalavras cont : contadores) {
System.out.printf("Arquivo '%s' tem %d palavras\n", cont.getNomeArquivo(), cont.getQtdPalavras());
}