Recebendo dados em Java
Eu recebi uma lista de alunos em um arquivo CSV e preciso cadastrá-los no meu sistema:
Alex Felipe;21
Cléber Nascimento;16
Felipe de Souza;25
João da Silva;18
Juliana Guimarães;18
Maria Cristina;23
Pâmela Aguiar;17
public class Aluno {
private final String nome;
private final int idade;
public Aluno(String nome, int idade) {
this.nome = nome;
this.idade = idade;
}
}
Preciso digitar as informações deles no meu sistema. Usarei a classe Scanner
do pacote java.util para receber os dados do teclado:
Scanner sc = new Scanner(System.in);
System.out.println("Digite o nome do aluno:");
String nome = sc.nextLine();
System.out.println("Informe a idade do aluno:");
int idade = sc.nextInt();
System.out.println("aluno: " + nome + "\\nidade: " + idade);
Pegando o primeiro resultado:
Digite o nome do aluno: Alex Felipe
Informe a data de nascimento do aluno: 21
aluno: Alex Felipe
idade: 21
O método nextLine()
permite a leitura de String
e o método nextInt()
permite a leitura de int
. Enviando os dados para o aluno:
Aluno aluno = new Aluno(nome, idade);
System.out.println(aluno);
Verificando a impressão:
nome: Alex Felipe idade: 21
Ótimo, consegui cadastrar um aluno! Agora vamos cadastrar o restante dos alunos:
Digite o nome do aluno: Cleber Nascimento Informe a idade do aluno: 16 nome: Cleber Nascimento idade: 16 Digite o nome do aluno: Felipe de Souza Informe a idade do aluno: 25 nome: Felipe de Souza idade: 25 Digite o nome do aluno: João da Silva Informe a idade do aluno: 18 nome: João da Silva idade: 18
...
Espera aí! Isso já está ficando cansativo! Será que eu vou ter que cadastrar todos esses alunos na unha? Se apenas com 7 está sendo esse sofrimento imagine com mais 30! Vai tirar a paciência de qualquer um!
Além de permitir a leitura de dados por meio do teclado, a classe Scanner
possibilita a leitura de arquivos! Basta informar no construtor que ao invés de ler pelo teclado(System.in), queremos ler um arquivo específico instanciando a classe File do pacote java.io:
Scanner sc = new Scanner(new File("usuarios.csv"));
Pronto! Agora precisaremos ler linha por linha fazendo iterações com um while por meio do método hasNext()
que informa se ainda existe linhas para ler:
while (sc.hasNext()) {
//O while só para quando não tiver mais linhas para ler
}
Para pegar o próximo elemento do arquivo usamos o método next()
:
while (sc.hasNext()) {
String elemento = sc.next();
System.out.println(elemento);
}
Se testarmos nosso código:
Alex Felipe;21
Cleber Nascimento;16
Felipe de Souza;25 ...
Ops! Dessa maneira eu não vou conseguir separar os dados do aluno... Além de fazer a leitura do arquivo, o Scanner
tem o método useDelimiter()
que delimita a leitura do elemento, ou seja, determina até que ponto precisa pegar o elemento, por exemplo, eu quero que ele pegue o elemento até aparecer um ";":
Scanner sc = new Scanner(new File("arquivo.csv"))
.useDelimiter(";");
Executando o código mais uma vez:
Alex Felipe 21
Cleber Nascimento 16
Felipe de Souza 25
...
Ótimo! Separei as informações, agora irei instanciar os meus alunos:
String nome = sc.next();
int idade = Integer.parseInt(sc.next());
Aluno aluno = new Aluno(nome, idade);
System.out.println(aluno);
Testando o nosso código:
Exception in thread "main"
java.lang.NumberFormatException: For input string: "21 Cleber Nascimento"
Que estranho... Problema na conversão? Que String grotesca é essa? Parecia que as informações de nome e idade estavam separadas corretamente... O que aconteceu nesse caso é que o nosso delimitador está separando as informações até o momento em que ele acha um ";" entre a idade e o próximo nome do aluno não existe um ";" tem apenas uma quebra de linha, ou seja, precisamos informar ao Scanner
que ao mesmo tempo que delimitamos pelo ";" queremos que ele delimita por quebra de linha também:
Scanner sc = new Scanner(new File("arquivo.csv")).useDelimiter(";|\\\\n");
O pipe(|) indica que queremos que delimite por ";" ou "\n" que significa quebra de linha. Testando novamente:
Exception in thread "main"
java.lang.NumberFormatException: For input string: "21 "
Outra Exception? Que doideira! Como podemos ver ele já separou a idade do nome do outro aluno, porém ele ainda deixou uma quebra de linha e por isso não foi possível fazer a conversão para int
. Nesse caso podemos usar o método trim()
da própria classe String
que ajusta o conteúdo contido na String
eliminando quebras de linhas ou espaços em branco:
String nome = sc.next();
int idade = Integer.parseInt(sc.next().trim());
Aluno aluno = new Aluno(nome, idade);
System.out.println(aluno);
Conferindo o resultado:
nome: Alex Felipe idade: 21
nome: Cleber Nascimento idade:
16 nome: Felipe de Souza idade: 25
...
Excelente! Agora o meu sistema é capaz de ler o arquivo CSV e cadastrar os alunos pra mim!
Vimos que para receber dados de meios externos em java nós podemos utilizar a classe Scanner
que tem a capacidade de receber dados por meio do teclado ou arquivos, porém nem sempre quando lemos as informações de um arquivo o resultado é esperado, então precisamos sempre verificar as seguintes informações:
- Se existir algum carácter que separa cada elemento use um delimitador
- Se for necessário utilizar mais de um delimitador utilize o pipe (|)
- Se sempre estiver pegando o próximo elemento ao invés da linha inteira, sempre use o delimitador '\n'
Gostou da classe Scanner? Quer conhecer outras alternativas para a classe Scanner
e outras bibliotecas da linguagem Java? Conheça a Formação Java.