Quando se começa a conhecer os princípios da programação, com o tempo surge a vontade do desenvolvedor iniciante a trabalhar com programas no modo texto (console). Com esse princípio, muitos começam a usar a classe Scanner, pois tem justamente a finalidade de facilitar a entrada de dados no modo Console. Essa classe apareceu a partir do Java 5, antes dessa versão era complicado criar programas que recebiam valores de variáveis no modo Console.
Conceito
O significado da classe Scanner para muitos no começo é um pouco complicado de entender, mas com o tempo o programador acaba se acostumando com a sua definição. Um scanner de texto simples pode analisar os tipos primitivos e strings usando expressões regulares.
A classe Scanner tem como objetivo separar a entrada dos textos em blocos, gerando os conhecidos tokens, que são sequências de caracteres separados por delimitadores que por padrão correspondem aos espaços em branco, tabulações e mudança de linha.
Com essa classe podem ser convertidos textos para tipos primitivos, sendo que esses textos podem ser considerados como objetos do tipo String, InputStream e arquivos.
Na Prática
Antes de tudo, é necessário saber algumas funções e aspectos que essa classe tem para exercer o funcionamento dentro do esperado. Quando invocada a classe Scanner, o compilador pedirá para fazer a seguinte importação:
Listagem 1: Importando a classe Scanner
import java.util.Scanner;
|
Como descrito na introdução, essa classe ajuda na leitura dos dados informados. Para fazer essa ação na prática, é necessário criar um objeto do tipo Scanner que passa como argumento o objeto System.in dentro construtor, do seguinte modo:
Listagem 2: Declarações do Scanner
import java.util.Scanner;
public class TestaDeclaracaoScanner {
public static void main(String[] args) {
Scanner sc1 = new Scanner(System. in );
String textoString = "Maria Silva" ;
Scanner sc2 = new Scanner(textoString);
}
}
|
Listagem 3: Contagem de tokens em uma string
import java.util.Scanner;
public class ContaTokens {
public static void main(String[] args) {
int i = 0;
Scanner sc = new Scanner(System. in );
System.out.print( "Digite um texto:" );
while (sc.hasNext()){
i++;
System.out.println( "Token: " +sc.next());
}
sc.close();
}
}
|
O objeto System.in é o que faz a leitura do que se escreve no teclado. Veja abaixo como são invocados alguns dos métodos principais que correspondem com a assinatura que retorna um valor do tipo que foi invocado. Ou seja, para cada um dos primitivos existe uma chamada do método para retornar o valor especificado na entrada de dados, sempre seguindo o formato nextTipoDado().
Listagem 4: Métodos invocados da classe Scanner
Scanner sc = new Scanner(System. in );
float numF = sc.nextFloat();
int num1 = sc.nextInt();
byte byte1 = sc.nextByte();
long lg1 = sc.nextLong();
boolean b1 = sc.nextBoolean();
double num2 = sc.nextDouble();
String nome = sc.nextLine();
|
Como a classe Scanner trabalha com entrada de dados, sempre é uma boa prática fazer o uso do try/catch para que os sistemas fiquem bem construídos. A Figura 1 mostra o exemplo do erro quando o código não tem tratamento de exceção. Nesse caso, o usuário tenta inserir letras em uma linha que esperava ler o valor do tipo double.
Figura 1: Demonstração da exceção InputMismatchException
Métodos da Classe
Na tabela abaixo são apresentados os principais métodos da classe Scanner.
Método | Descrição |
close() | Fecha o escaneamento de leitura. |
findInLine() | Encontra a próxima ocorrência de um padrão ignorando máscaras ou strings ignorando delimitadores. |
hasNext() | Retorna um valor booleano verdadeiro (true) se o objeto Scanner tem mais dados de entrada. |
hasNextXyz() | Retorna um valor booleano como verdadeiro (true) se a próxima entrada a qual Xyz pode ser interceptada como Boolean, Byte, Short, Int, Long, Float ou Double. |
match() | Retorna o resultado da pesquisa do último objeto Scanner atual. |
next() | Procura e retorna a próxima informação do objeto Scanner que satisfazer uma condição. |
nextBigDecimal(), nextBigInteger() | Varre a próxima entrada como BigDecimal ou BigInteger. |
nextXyz() | Varre a próxima entrada a qual Xyz pode ser interceptado como boolean, byte, short, int, long, float ou double. |
nextLine() | Mostra a linha atual do objeto Scanner e avança para a próxima linha. |
radix() | Retorna o índice atual do objeto Scanner. |
remove() | Essa operação não é suportada pela implementação de um Iterator. |
skip() | Salta para a próxima pesquisa de um padrão especificado ignorando delimitadores. |
string() | Retorna uma string que é uma representação do objeto Scanner. |
Tabela 1: Métodos da classe Scanner
Vamos mostrar alguns exemplos práticos do que pode ser feito com a classe Scanner.
As Listagens 5 e 6 fazem uso da programação orientada a objetos (POO). O objetivo é mostrar o que se pode fazer usando as lições básicas aprendidas na manipulação de objetos. Os métodos setters (setNomeAtributo) guardam o valor digitado que depois são usados para gerar a saída de cada objeto criado na lista.
Listagem 5: Classe pessoa com o método toString() sobrescrito
public class Pessoa {
private Integer codigo;
private String nome;
private String endereco;
private Integer idade;
public Integer getCodigo() {
return codigo;
}
public void setCodigo(Integer codigo) {
this .codigo = codigo;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this .nome = nome;
}
public String getEndereco() {
return endereco;
}
public void setEndereco(String endereco) {
this .endereco = endereco;
}
public Integer getIdade() {
return idade;
}
public void setIdade(Integer idade) {
this .idade = idade;
}
@Override
public String toString() {
return "Código: " +codigo+ "" +
"\n" + "Nome: " +nome+ "" +
"\n" + "Endereço: " +endereco+ "" +
"\n" + "Idade: " +idade+ "\n" ;
}
}
|
Na Listagem 6 é praticado um pouco de orientação a objetos. Esse código mostra que podem ser armazenados vários objetos Pessoa em uma lista e mais tarde impressos seus dados.
Faça um teste, insira dois ou mais cadastros e logo após escolha a opção 2. Nesse caso, serão impressos todos os objetos Pessoa guardados na lista.
Listagem 6: Classe testadora usando a POO
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class TestaPessoaScanner {
public static void main(String[] args) {
dadosPessoas();
}
public static void dadosPessoas(){
Scanner sc = new Scanner(System. in );
Pessoa pessoa;
List<Pessoa> listaPessoas = new ArrayList<Pessoa>();
int opcao = 0;
do {
System.out.println( "## Escolha uma das opções abaixo ##" );
System.out.println( "Opção 1 - Cadastra pessoas" );
System.out.println( "Opção 2 - Imprime pessoas cadastradas" );
System.out.println( "Opção 0 - Sair do programa" );
System.out.println( "_______________________" );
System.out.print( "Digite aqui sua opção: " );
opcao = Integer.parseInt(sc.nextLine());
if (opcao == 1){
pessoa = new Pessoa();
System.out.print( "Digite o código: " );
pessoa.setCodigo(Integer.parseInt(sc.nextLine()));
System.out.print( "Digite o nome: " );
pessoa.setNome(sc.nextLine());
System.out.print( "Digite o endereço: " );
pessoa.setEndereco(sc.nextLine());
System.out.print( "Digite a idade: " );
pessoa.setIdade(Integer.parseInt(sc.nextLine()));
System.out.println();
listaPessoas.add(pessoa);
} else if (opcao == 2){
if (listaPessoas.isEmpty()){
System.out.println( "Não existem pessoas cadastradas, pressione uma tecla para continuar!" );
sc.nextLine();
} else {
System.out.println(listaPessoas.toString());
System.out.println( "Pressione um tecla para continuar." );
sc.nextLine();
} }
} while (opcao != 0);
sc.close();
}
}
|
Para concluir, vamos mostrar um recurso bem interessante que é possível fazer com a classe Scanner. A Listagem 7 mostra a possibilidade de ler o conteúdo de um usando Java.
Listagem 7: Leitura do conteúdo de um arquivo
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class LerArquivo {
public static void lerTexto(String nomeArquivo){
try {
File arquivo = new File(nomeArquivo);
Scanner sc = new Scanner(arquivo);
while (sc.hasNext()){
System.out.print(sc.nextLine());
}
sc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
lerTexto( "poema.txt" );
}
}
|
A Figura 2 mostra a localização do arquivo que fica dentro da pasta do pacote, o conteúdo do arquivo e a saída.
Figura 2: Evidência da saída do texto
Conclusão
Então foi mostrada a importância do uso da classe Scanner, sobre a qual foram apresentados conceitos, características, métodos e muitas práticas. Um dos objetivos foi de trabalhar com POO, justamente para mostrar para os iniciantes o pequeno esforço que pode ser feito e a imensidão de conhecimento que pode ser adquirido em um simples exemplo.
Fico por aqui e espero que tenham gostado, até a próxima.
Referências