Olá! Nossa aula de hoje será especial! Antes disso, ao resolver problemas e escrever programas, o algoritmo era simples: escrevemos algum código, executamos o método main() , o programa faz o que é exigido dele e sai. Mas agora tudo vai mudar! Hoje aprenderemos como interagir verdadeiramente com o programa: vamos ensiná-lo a responder às nossas ações! Você já deve entender onde estamos indo com isso. Dedicaremos esta palestra a uma análise detalhada de uma das classes da linguagem Java – Scanner. Esta classe será útil se você precisar ler os dados inseridos pelos usuários. Antes de começarmos a aprender o código, diga-me, você já encontrou um dispositivo como um scanner? Certamente sim. A estrutura interna do scanner é bastante complexa, mas a essência do seu trabalho é bastante simples: ele lê os dados que o usuário insere nele (por exemplo, um passaporte ou apólice de seguro) e armazena as informações lidas na memória (por exemplo , em forma de imagem). Então hoje você criará seu próprio scanner! Claro, ele não consegue lidar com documentos, mas consegue lidar muito bem com informações de texto :) Vamos lá!
Classe de scanner Java
A primeira e mais importante coisa que precisamos conhecer é a aulajava.util.Scanner
. Sua funcionalidade é muito simples. Como um scanner real, ele lê dados da fonte que você especifica. Por exemplo, de uma linha, de um arquivo, do console. Em seguida, ele reconhece essas informações e as processa conforme necessário. Vamos dar o exemplo mais simples:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner("I love you, Petra creation,\n" +
"I love your stern, slim look,\n" +
"Neva sovereign current,\n" +
"Coastal granite");
String s = scanner.nextLine();
System.out.println(s);
}
}
Criamos um objeto scanner e especificamos uma fonte de dados para ele (uma string com texto). O método nextLine()
acessa a fonte de dados (nosso texto com quadras), encontra ali a próxima linha que ainda não leu (no nosso caso, a primeira) e a retorna. Depois disso, enviamos para o console: Saída do console:
Люблю тебя, Peterа творенье,
Podemos usar o método nextLine()
várias vezes e produzir todo o trecho do poema:
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner("I love you, Petra creation,\n" +
"I love your stern, slim look,\n" +
"Neva sovereign current,\n" +
"Coastal granite");
String s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
s = scanner.nextLine();
System.out.println(s);
}
}
Cada vez que nosso scanner dará um passo à frente e lerá a próxima linha. O resultado do programa é enviado para o console:
Люблю тебя, Peterа творенье,
Люблю твой строгий, стройный вид,
Невы державное теченье,
Береговой ее гранит
Como já dissemos, a fonte de dados do scanner pode ser não apenas uma string, mas também, por exemplo, um console. Notícias importantes para nós: se antes só produzíamos dados lá, agora inseriremos os dados pelo teclado! Vamos ver o que mais a classe Scanner pode fazer :
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number:");
int number = sc.nextInt();
System.out.println("Thank you! You entered a number" + number);
}
}
O método nextInt()
lê e retorna o número inserido. Em nosso programa, é usado para atribuir um valor a uma variável number
. Parece mais um scanner de verdade! O programa pede ao usuário para inserir qualquer número em uma linha. Após o usuário ter feito isso, o programa agradece, exibe o resultado do seu trabalho no console e finaliza. Mas ainda temos um problema sério. O usuário pode cometer um erro e inserir algo errado. Aqui está um exemplo de quando nosso programa atual pararia de funcionar:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number:");
int number = sc.nextInt();
System.out.println("Thank you! You entered a number" + number);
}
}
Vamos tentar inserir a string “JavaRush” em vez de um número: Saída do console:
Enter the number:
JavaRush
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Main.main(Main.java:10)
Process finished with exit code 1
Opa, está tudo ruim -_- Para evitar tais situações, precisamos encontrar uma forma de validar os dados que o usuário insere. Por exemplo, se o usuário inserir algo diferente de um número, seria bom exibir um aviso no console de que a informação inserida não é um número e, se tudo estiver em ordem, exibir um texto de confirmação. Mas para fazer isso, precisamos realmente “olhar para o futuro” – descobrir o que vem a seguir em nosso fluxo. O Scanner em Java pode fazer isso? Como ele pode! E para isso possui todo um grupo de métodos: hasNextInt()
- o método verifica se a próxima parte dos dados inseridos é um número ou não (retorna verdadeiro ou falso, respectivamente). hasNextLine()
— verifica se o próximo dado é uma string. hasNextByte()
, hasNextShort()
, hasNextLong()
, hasNextFloat()
, hasNextDouble()
- todos esses métodos fazem o mesmo para outros tipos de dados. Vamos tentar mudar nosso programa para ler números:
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number:");
if (sc.hasNextInt()) {
int number = sc.nextInt();
System.out.println("Thank you! You entered a number" + number);
} else {
System.out.println("Sorry, but this is clearly not a number. Restart the program and try again!");
}
}
}
Agora nosso programa verifica se o próximo caractere digitado é um número ou não. E somente se for, exibe uma confirmação. Se a entrada não passar no teste, o programa percebe isso e pede que você tente novamente. Essencialmente, você pode se comunicar com o objeto Scanner e saber antecipadamente que tipo de dados esperar. “Ei, scanner, o que vem a seguir? Número, string ou algo mais? Número? E qual deles - int
, short
, long
?” Essa flexibilidade lhe dá a oportunidade de construir a lógica do seu programa dependendo do comportamento do usuário. Outro método importante que vale a pena prestar atenção é useDelimiter()
. Este método recebe a string que você deseja usar como delimitador. Por exemplo, de repente nos interessamos pela poesia japonesa e decidimos usar o scanner para ler vários haicais do grande poeta Matsuo Basho. Mesmo que três versículos diferentes nos sejam dados em uma linha desajeitada, podemos facilmente separá-los e formatá-los de maneira adequada:
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner("On a Bare Branch" +
"Raven sits alone.'" +
"Autumn evening." +
"''***''" +
"There's such a moon in the sky,'" +
"Like a tree cut down at the root:'" +
"A fresh cut turns white." +
"''***''" +
"How the river has overflowed!" +
"The heron wanders on short legs,'" +
"Knee-deep in water.");
scan.useDelimiter("'");
while (scan.hasNext()) {
System.out.println(scan.next());
}
scan.close();
}
}
Usamos o método useDelimeter() da classe Scanner como separador de linhas : ele é responsável por dividir os dados recebidos em partes. No nosso caso, uma aspa simples ( "'" ) é passada como argumento e usada para separar strings . O texto após esta citação aparece em uma nova linha porque no loop while estamos usando o método println() da classe System para ler os dados. Como resultado, teremos um belo resultado no console, assim como nos livros:
На голой ветке
Ворон сидит одиноко.
Осенний вечер.
***
В небе такая луна,
Словно дерево спилено под корень:
Белеет свежий срез.
***
Как разлилась река!
Цапля бредет на коротких ножках,
По колено в воде.
No mesmo exemplo, há mais um método ao qual você definitivamente deve prestar atenção - close()
. Como qualquer objeto que funciona com fluxos de E/S, o scanner deve ser fechado ao concluir seu trabalho para não consumir mais os recursos do nosso computador. Nunca se esqueça do método close()
!
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number:");
int number = sc.nextInt();
System.out.println("Thank you! You entered a number" + number);
sc.close();//Now we did everything right!
}
}
Isso é tudo! Como você pode ver, a classe Scanner é bastante fácil de usar e muito útil! :)
GO TO FULL VERSION