Ler dados do teclado com a classe Scanner
No desenvolvimento em Java, a leitura de dados do teclado é uma tarefa comum, facilitada pela classe java.util.Scanner
desde a versão 5. No entanto, iniciantes frequentemente enfrentam problemas com o salto de linha ao utilizar essa classe. Este tutorial abordará como solucionar esse problema específico, garantindo uma leitura de dados eficiente e sem complicações. Vamos explorar as melhores práticas e fornecer exemplos práticos para ajudar você a dominar o uso da classe Scanner em Java.
1. Criando a classe Teclado
Para iniciar o tutorial vamos criar a classe Teclado
– Listagem 1 – com alguns atributos que serão preenchidos com os dados que serão capturados da leitura do teclado, mais o método toString()
e main()
.
package com.mballem.lerteclado;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Teclado {
private long id;
private String firstName;
private String surname;
private int age;
@Override
public String toString() {
return "Teclado{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", surname='" + surname + '\'' +
", age=" + age +
'}' + "\n";
}
public static void main(String[] args) {
}
}
2. Lendo do teclado com Scanner
Agora será criado um método simples para a leitura de dados do teclado, nesse método vou apresentar também o problema do salto de linhas e algumas formas de resolvê-lo. Veja no método readingOne()
– Listagem 2 – que o código aparentemente não apresenta problema algum.
package com.mballem.lerteclado;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Teclado {
//atributos e toString() omitidos nesta listagem
public static void main(String[] args) {
readingOne();
}
private static void readingOne() {
Scanner scanner = new Scanner(System.in);
Teclado t = new Teclado();
System.out.print("Enter your id: ");
t.id = scanner.nextInt();
System.out.print("Enter your first name: ");
t.firstName = scanner.nextLine();
System.out.print("Enter your last name: ");
t.surname = scanner.nextLine();
System.out.print("Enter your age: ");
t.age = scanner.nextInt();
System.out.println(t.toString());
}
}
O código da Listagem 2 quando for executado vai resultar no problema exibido na Figura 1. Veja na marcação em vermelho que após o id
ser informado, a linha first name
não foi digitada e sim a linha surname
. Isso aconteceu porque o método nextInt()
da classe Scanner
deixa no buffer a instrução da tecla pressionada, ou seja, um \n
(123456789\n
). Como o método nextInt()
retorna apenas um valor inteiro, o \n
acaba sendo adicionado ao próximo método que é o nextLine()
. Assim, o método recebe uma instrução como se o usuário tivesse pressionado o e então pula para a próxima linha.
Figura 1 – Falha no método readingOne()
Uma forma para resolver esse problema é substituir o método nextLine()
pelo método next()
, como se pode observar na Listagem 3. Desta forma podemos ler perfeitamente as instruções conforme demonstrado na Figura 2.
package com.mballem.lerteclado;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Teclado {
//atributos e toString() omitidos nesta listagem
public static void main(String[] args) {
readingTwo();
}
private static void readingTwo() {
Scanner scanner = new Scanner(System.in);
Teclado t = new Teclado();
System.out.print("Enter your id: ");
t.id = scanner.nextInt();
System.out.print("Enter your first name: ");
t.firstName = scanner.next();
System.out.print("Enter your last name: ");
t.surname = scanner.next();
System.out.print("Enter your age: ");
t.age = scanner.nextInt();
System.out.println(t.toString());
}
}
Figura 2 – Método readingTwo()
Mas ainda temos um problema, o método next()
não permite que se use, por exemplo, o espaço entre palavras. Se for digitado algo como “João Luiz” o método irá separar o nome “João” de “Luiz”, veja o acontece na Figura 3. Observe que na marcação em vermelho, após ter sido digitado o nome “João Luiz” a linha seguinte foi saltada, indo direto para a próxima linha. Porém, quando foi impresso o objeto, o nome “Luiz” apareceu no atributo surname
, o que não deveria ter acontecido.
Figura 3 – Falha ocorrida em readingTwo
Uma forma para resolver de vez esse problema do salto de linhas é usar apenas o método nextLine()
, mesmo que um atributo não seja do tipo String
. Bastaria apenas fazer a conversão de tipos, como descrito na Listagem 4. Confira na Figura 4 o resultado da execução do método readingThree()
.
package com.mballem.lerteclado;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Teclado {
//atributos e toString() omitidos nesta listagem
public static void main(String[] args) {
readingThree();
}
private static void readingThree() {
Scanner scanner = new Scanner(System.in);
Teclado t = new Teclado();
System.out.print("Enter your id: ");
t.id = Long.parseLong(scanner.nextLine());
System.out.print("Enter your first name: ");
t.firstName = scanner.nextLine();
System.out.print("Enter your last name: ");
t.surname = scanner.nextLine();
System.out.print("Enter your age: ");
t.age = Integer.parseInt(scanner.nextLine());
System.out.println(t.toString());
}
}
Figura 4 – Problemas resolvidos
Você pode agora criar um menu pelo teclado, como exemplo veja a Listagem 5.
package com.mballem.lerteclado;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Teclado {
//atributos e toString() omitidos nesta listagem
public static void main(String[] args) {
readingMenu();
}
private static void readingMenu() {
Scanner scanner = new Scanner(System.in);
Teclado t;
List list = new ArrayList();
int option = 0;
do {
System.out.println("1. Add User");
System.out.println("2. Print Users");
System.out.println("0. Exit");
System.out.print("> ");
option = Integer.parseInt(scanner.nextLine());
if (option == 1) {
t = new Teclado();
System.out.print("Enter your id: ");
t.id = Long.parseLong(scanner.nextLine());
System.out.print("Enter your first name: ");
t.firstName = scanner.nextLine();
System.out.print("Enter your last name: ");
t.surname = scanner.nextLine();
System.out.print("Enter your age: ");
t.age = Integer.parseInt(scanner.nextLine());
list.add(t);
} else if (option == 2) {
System.out.println(list.toString());
}
} while (option != 0);
}
}
Conclusão
Neste tutorial, exploramos como utilizar a classe Scanner
para ler dados do teclado em Java, identificando e resolvendo o problema comum do salto de linha. Vimos como os métodos nextInt()
e nextLine()
podem causar confusões e como substituí-los apropriadamente por next()
ou nextLine()
com conversão de tipos. Com os exemplos práticos fornecidos, você agora pode implementar uma leitura de dados mais robusta e eficiente em seus projetos Java. Dominar essas técnicas é essencial para evitar erros comuns e garantir a precisão da entrada de dados no seu aplicativo.
Saiba mais
- Documentação da classe java.util.Scanner http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html