Como funciona a classe Scanner do Java?

Veja neste artigo o trabalho que se consegue realizar com a classe Scanner no Java. Vamos falar sobre o conceito, apresentar características dessa classe e alguns exemplos.

Usando a Classe Scanner no Java

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 da Classe Scanner no Java

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:

import java.util.Scanner;
Listagem 1: Importando a classe 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:

import java.util.Scanner; public class TestaDeclaracaoScanner { public static void main(String[] args) { //Lê a partir da linha de comando Scanner sc1 = new Scanner(System.in); String textoString = "Maria Silva"; //Lê a partir de uma String Scanner sc2 = new Scanner(textoString); } }
Listagem 2: Declarações do Scanner.
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(); //Encerra o programa } }
Listagem 3: Contagem de tokens em uma string.

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().

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();
Listagem 4: Métodos invocados da classe Scanner.

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étodoDescriçã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.

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"; } }
Listagem 5: Classe pessoa com o método toString() sobrescrito.

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.

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){ //Cria um novo objeto 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(); //Guarda o objeto pessoa em uma lista. 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(); } }
Listagem 6: Classe testadora usando a POO.

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.

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"); //trocar pelo caminho do arquivo desejado. } }
Listagem 7: Leitura do conteúdo de um arquivo.

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

Artigos relacionados