Introdução a Java através de exemplos
Programação 2 – Aulas 1 e 2
Linguagem muito
poderosa embora simples
Permite
portabilidade
Muito
usada em programação em rede
◦
Server Programming
◦
Aplicações de e-commerce, e-business, etc.
◦ Aplicações para
acesso via Internet, intranet, etc.
package p2.exemplos; /* * O
primeiro programa em Java: Hello World * Autor:
Jacques Sauvé */ // Todo programa tem um ponto de
entrada: // o "método" main de alguma
"classe" public class Hello { public static void main(String[] args) { System.out.println("Hello,
world!"); } } |
A linha abaixo
package p2.exemplos; |
É usada
para indicar que este programa faz parte de um "pacote" que pode
conter vários programas
É uma forma de organizar vários programas, da mesma forma que "pastas" ou "diretórios" são usados para organizar arquivos num sistema de arquivos
(há mais um tipo a ser visto adiante)
/* * O primeiro programa em Java: Hello World * Autor: Jacques Sauvé */ // Todo programa tem um ponto
de entrada: o |
Esqueça,
por enquanto, o que significam “método”, “classe”, “public”,
“class”, “static” e “void”
◦ "Método"
é semelhante a "module" em Python
◦ Outros
nomes: sub-rotina, função, procedimento, procedure, ...
O nome do
programa é Hello
◦ Por
convenção, deve iniciar com uma letra maiúscula
◦ Observe que
o programa Hello está obrigatoriamente armazenado no arquivo Hello.java
◦ Java é
"case-sensitive" (reconhece diferença de caixa)
Até entender detalhes, sempre use as primeiras duas linhas de código do exemplo, trocando apenas o nome do programa (Hello)
public class Hello { public static void main(String[] args) { |
"{"
significa "BEGIN" e "}" significa "END"
Observe a
forma de imprimir
Observe a formação de uma constante do tipo string ("Hello, world!")
Vamos compilar o programa (no Windows, UNIX, etc.)
Isso é desnecessário em Python que é interpretado
javac Hello.java |
O comando javac é o compilador Java
O resultado deve estar no arquivo Hello.class (verifique)
Agora,
vamos executar o programa:
java –cp . p2.exemplos.Hello |
O
comando java é a "Java Virtual Machine" (JVM) que
sabe executar um programa Java compilado com o comando java e presente no arquivo Hello.class
◦
Isso é diferente de outras linguagens
(C, C++) que são diretamente executáveis após a compilação
◦
Motivo: independência de
plataforma: Um programa em Java executa em qualquer lugar onde houver uma JVM,
sem recompilação
A saída é:
Hello, world! |
A saída é
"a caractere"
◦ É possível
fazer interfaces gráficas com Java
◦ A
disciplina de laboratório tratará do assunto
É possível
usar ambientes integrados de desenvolvimento (IDE) para programar e depurar em
Java
◦ Eclipse é particularmente popular
Ler 3 números inteiros da entrada, imprimir o menor e o maior
◦ Entrada de
dados
◦ Tipos
básicos
◦ Variáveis
◦ Decisões
simples
A primeira
solução vem a seguir:
package p2.exemplos; import java.util.Scanner; public class MinMax1 { public
static void main(String[] args) { Scanner sc = new Scanner(System.in); int n1, n2, n3; System.out.print("Entre
com o primeiro inteiro: "); n1 = sc.nextInt(); System.out.print("Entre
com o segundo inteiro: "); n2 = sc.nextInt(); System.out.print("Entre
com o terceiro inteiro: "); n3 = sc.nextInt(); if (n1 > n2) { if (n1 > n3) { if (n2 < n3) { System.out.println("O
menor numero eh: " + n2); } else { System.out.println("O
menor numero eh: " + n3); } System.out.println("O
maior numero eh: " + n1); } else { if (n1 < n2) { System.out.println("O
menor numero eh: " + n1); } else { System.out.println("O
menor numero eh: " + n2); } System.out.println("O
maior numero eh: " + n3); } } else { if (n2 > n3) { if (n1 < n3) { System.out.println("O
menor numero eh: " + n1); } else { System.out.println("O
menor numero eh: " + n3); } System.out.println("O
maior numero eh: " + n2); } else { if (n1 < n2) { System.out.println("O
menor numero eh: " + n1); } else { System.out.println("O
menor numero eh: " + n2); } System.out.println("O
maior numero eh: " + n3); } } } } |
Compilando
e rodando o programa:
javac MinMax1.java java –cp ..\.. p2.exemplos.MinMax1 |
Uma saída
típica do programa:
Entre com o primeiro inteiro: 3 Entre com o segundo inteiro: 9 Entre com o terceiro inteiro: 123 O menor numero eh: 3 O maior numero eh: 123 |
A linha:
import
java.util.Scanner; |
É
usada para dizer ao Java que usaremos alguma coisa externa ao nosso programa (a
"classe" Scanner)
A linha:
Scanner sc = new Scanner(System.in); |
Cria um
"Scanner" que é usado para ler dados da entrada
◦ O que significa “new”, “System.in” serão explicados adiante
A linha:
int n1, n2, n3; |
Declara
três variáveis inteiras para uso posterior
◦ Por convenção, variáveis iniciam com letra minúscula
A linha…
n1 = sc.nextInt(); |
… lê um
inteiro da entrada
Também poderíamos ter feito assim:
int n1 = sc.nextInt(); |
As linhas:
if (n2 < n3) { System.out.println("O menor
numero eh: " + n2); } else { System.out.println("O menor numero eh:
" + n3); } |
Mostram
uma decisão
Duas dessas linhas também mostram a concatenação de strings com o operador +
◦ Falamos que, em Java, o operador "+" está overloaded porque ele significa adição de números e também concatenação de strings, dependendo dos seus operandos
◦ É o único operador que sofre overload
A seguir,
uma segunda versão do programa
package p2.exemplos; import java.util.Scanner; /* * "Ler 3 números inteiros da entrada,
imprimir o menor * e o
maior" * * Autor: Jacques Sauvé */ public class MinMax2 { public static void main(String[]
args) {
Scanner sc = new
Scanner(System.in); int
n1, n2, n3; System.out.print("Entre com o primeiro inteiro: "); n1 = sc.nextInt(); System.out.print("Entre com o segundo inteiro: "); n2 = sc.nextInt(); System.out.print("Entre com o terceiro inteiro: "); n3 = sc.nextInt(); int mínimo; int máximo; if (n1 > n2) { if (n1 > n3) { if (n2 < n3) { mínimo = n2; } else { mínimo = n3; } máximo = n1; } else { if (n1 < n2) { mínimo = n1; } else { mínimo = n2; } máximo = n3; } } else { if (n2 > n3) { if (n1 < n3) { mínimo = n1; } else { mínimo = n3; } máximo = n2; } else { if (n1 < n2) { mínimo = n1; } else { mínimo = n3; } máximo = n3; } } System.out.println("O menor numero eh: " + mínimo); System.out.println("O maior numero eh: " + máximo); } } |
Observe que estamos usando variáveis com
acentuação
◦
Isso é
possível porque Java usa Unicode como código de caracteres
Perguntas sobre este programa:
◦ Você achou
o programa “bem escrito”?
◦ É fácil de
entender?
◦ É fácil
trocar as mensagens de saída por outras?
◦ É fácil
assegurar-se de que não há bugs?
i)
Na realidade, um dos programas acima tem um bug: ache o!
◦ É fácil
estender para 4 números lidos na entrada?
Que tal o
seguinte programa que resolve o mesmo problema:
package p2.exemplos; import java.util.Scanner; /* * "Ler 3 números inteiros da entrada,
imprimir o *
menor e o maior" * * Autor: Jacques Sauvé */ public class MinMax3 { public static void main(String[]
args) {
Scanner sc = new
Scanner(System.in);
int num; int mínimo = Integer.MAX_VALUE; int máximo = Integer.MIN_VALUE; System.out.print("Entre com o primeiro inteiro: "); num = sc.nextInt(); if (num < mínimo) { mínimo = num; } if (num > máximo) { máximo = num; } System.out.print("Entre com o segundo inteiro: "); num = sc.nextInt(); if (num < mínimo) { mínimo = num; } if (num > máximo) { máximo = num; } System.out.print("Entre com o terceiro inteiro: "); num = sc.nextInt(); if (num < mínimo) { mínimo = num; } if (num > máximo) { máximo = num; } System.out.println("O menor numero eh: " + mínimo); System.out.println("O maior numero eh: " + máximo); } } |
É muito
mais simples, não é?
◦ Por quê?
A
solução pode ser ainda melhor!!! Veja o programa abaixo:
package p2.exemplos; import java.util.Scanner; /* * "Ler 3 números inteiros da entrada,
imprimir o *
menor e o maior" * * Autor: Jacques Sauvé */ public class MinMax4 { public static void main(String[]
args) {
final int NÚMEROS_A_LER = 3; Scanner sc = new Scanner(System.in);
int mínimo =
Integer.MAX_VALUE; int máximo = Integer.MIN_VALUE; for (int
i = 0; i < NÚMEROS_A_LER; i++) { System.out.print("Entre com o proximo inteiro:"); int num = sc.nextInt(); if (num < mínimo) { mínimo = num; } if (num > máximo) { máximo = num; } } System.out.println("O menor numero eh: " + mínimo); System.out.println("O maior numero eh: " + máximo); } } |
NÚMEROS_A_LER é
declarado como “final” para indicar que é uma constante
◦ Como "const" em Pascal ou C
Por
convenção, usam-se letras maiúsculas para constantes
◦ Como em Python, C, C++
Melhor usar
constantes simbólicas do que constantes numéricas
◦ Programa fica mais simples de
entender
Observe
como fazer um laço "for" na linha:
for (int i = 0; i < NÚMEROS_A_LER; i++) { //Corpo do for será repetido NÚMEROS_A_LER
vezes! // Corpo executado até condição
ser satisfeita } |
A
expressão i++ significa i = i+1
Observe
também onde a variável “num” foi declarada:
int num =
sc.nextInt(); |
De forma
geral, é bom declarar uma variável perto de onde ela é usada
◦ Fizemos a mesma
coisa com a declaração da variável do laço (“i”)
Ainda
podemos deixar o programa em si mais limpo. Veja a versão abaixo:
package p2.exemplos; import java.util.Scanner; /* * "Ler 3 números inteiros da entrada,
imprimir o *
menor e o maior" * * Autor: Raquel Lopes */ public class
MinMax5 { public static void
main(String[] args) { final int
NÚMEROS_A_LER = 3; Scanner sc = new Scanner(System.in); int mínimo = Integer.MAX_VALUE; int máximo = Integer.MIN_VALUE; for (int
i = 0; i < NÚMEROS_A_LER; i++) { int num = recebeProximoInteiro(sc); mínimo = menorNumeroEntre(mínimo,
num); máximo = maiorNumeroEntre(máximo,
num); } System.out.println("O menor numero eh: " + mínimo); System.out.println("O maior numero eh: " + máximo); } private static int
maiorNumeroEntre(int
numero1, int numero2) { return numero2 > numero1? numero2: numero1; } private static int
menorNumeroEntre(int
numero1, int numero2) { return numero2 < numero1? numero2: numero1; } private static int
recebeProximoInteiro(Scanner sc) { System.out.print("Entre com o proximo inteiro:"); int num = sc.nextInt(); return num; } } |
Note a
presença do operador ternário nos métodos maiorNumeroEntre e menorNumeroEntre
private static int
maiorNumeroEntre(int
numero1, int numero2) { return numero2 > numero1? numero2: numero1; } //Equivale
a: private static int
maiorNumeroEntre(int
numero1, int numero2) { if
(numero2 > numero1) { return numero2; } return numero1; } |
Esqueça por
enquanto a palavra “private”
◦ Criamos
métodos, que são como funções que podem ser chamadas de dentro do main;
◦ Também
seria possível chamar estes métodos dentro de outros métodos, como veremos mais
adiante.
Criamos
três métodos: recebeProximoInteiro, menorNumeroEntre e maiorNumeroEntre
◦ Criação de
métodos deixa o programa mais limpo, isto é, mais fácil de entender
◦ Criação de
métodos permite que eles sejam reusados em outras partes do mesmo programa ou
até em outros programas
i) Reuso é um
requisito geralmente perseguido quando programamos no paradigma orientado a
objetos
Antes um pouco de teoria
◦ Não precisa decorar essas coisas!
Basta saber que existem… (referências são feitas para se consultar!)
Tipos
primitivos, limites de representação e constantes:
Tipo
primitivo |
Tamanho |
Mínimo |
Máximo |
Exemplos
de Constantes |
boolean |
1 bit |
- |
- |
true,
false |
char |
16 bits |
Unicode 0 |
Unicode
65.535 |
'a' (letra
a) |
byte |
8 bits |
-128 |
+127 |
97, -23 |
short |
16 bits |
-215 |
+215-1 |
17569,
-21875 |
int |
32 bits |
-231 |
+231-1 |
1876345240,
|
long |
64 bits |
-263
|
+263-1 |
123981723971982318273L, |
float |
32 bits |
aprox -1038
|
aprox +1038
|
-3.4F |
double |
64 bits |
aprox -10308
|
aprox +10308
|
-3.4 |
void |
- |
- |
- |
indica
ausência de tipo |
A
conversão entre tipos, quando necessária, é feita com casts explícitos
double x =
8.89; int n = (int)x; // n terá valor 8 |
Operadores
◦ + (soma)
◦ -
(subtração)
◦ (multiplicação)
◦ / (divisão)
◦ % (módulo)
◦ Há
operadores unários - e +
◦ Operadores
binários podem ser seguido de =
soma +=
nota*peso; // equivalente a soma = soma +
nota*peso |
Outros operadores:
◦ Operador de String + (overloaded)
◦ Operadores de auto-incremento e auto-decremento ++ e --
númeroDeAlunos++;
// equivalente a númeroDeAlunos = númeroDeAlunos + 1 númeroDeAlunos--; // equivalente a númeroDeAlunos = númeroDeAlunos - 1 if(númeroDeAlunos--
> 0) // equivalente a testar númeroDeAlunos e depois decrementar if(--númeroDeAlunos
> 0) // equivalente a decrementar e depois testar númeroDeAlunos |
Operadores relacionais:
◦ <
(menor)
◦ <=
(menor ou igual)
◦ >
(maior)
◦ >= (maior
ou igual)
◦ == (igual)
◦ != (não
igual)
Operadores lógicos
◦ &&
(AND)
◦ || (OR)
◦ ! (NOT)
◦ Exemplos:
if(númeroDeAlunos > MAX_ALUNOS || númeroDeProfessores > MAX_PROFS) …
if(ano % 4 == 0 && ano % 100 != 0 || ano % 400 == 0)… // ano bissexto |
Operadores
de bits e de deslocamento
◦ &, &=, |, |=, ^, ^=, ~
◦ Não falaremos deles aqui
Operador
ternário
◦ Para escrever uma operação
condicional sem usar if-else
◦ Exemplo segue
// a linha seguinte média = númeroDeNotas == 0 ? 0.0 :
soma/númeroDeNotas; // é equivalente às linhas
seguintes if(númeroDeNotas
== 0) {
média = 0.0; } else {
média = soma/númeroDeNotas; } |
De forma geral, as precedências “esperadas” funcionam
// a linha seguinte if(
númeroDeAlunos > MAX_ALUNOS || númeroDeProfessores
> MAX_PROFS) … // não precisa de parênteses,
pois é equivalente a if((númeroDeAlunos
> MAX_ALUNOS) || (númeroDeProfessores > MAX_PROFS)) … |
Existe uma
tabela de precedências:
Operadores |
Precedência |
[] . () |
Mais alta |
! ~ ++ -- +
(unário) - (unário) (cast) new |
|
* / % |
|
+ - |
|
<<
>> >>> |
|
< <=
> >= instanceof |
|
== != |
|
& |
|
^ |
|
| |
|
&& |
|
|| |
|
?: |
|
= += -= *=
/= %= &= |= ^= <<= >>= >>>= |
Mais baixa |
Na dúvida, use parênteses
Não decore a tabela de precedências!
Abaixo segue um programa exemplo
◦ Este programa auxilia o planejamento
da aposentadoria
package p2.exemplos; import java.util.Scanner; /* * Planejamento de aposentadoria * Autor: Raquel Lopes */ public class
Aposentadoria { public static void
main(String[] args) { final double QUANTIA_MINIMA_TOTAL = 10000; final double MENOR_CONTRIBUICAO = 200; System.out.print("Quanto dinheiro voce quer para se
aposentar? "); double alvo = recebeDoubleMaiorQue(QUANTIA_MINIMA_TOTAL); System.out.print("Quanto dinheiro voce vai contribuir todo
ano?"); double contribuicaoAnual = recebeDoubleMaiorQue(MENOR_CONTRIBUICAO); System.out.print("Taxa de juros (ex.: digite 0,075 para
7,5%): "); double juros = recebePercentual(); System.out.println("Voce pode se aposentar em " + computaAnosDeContribuicao(alvo,
contribuicaoAnual, juros) + "
anos."); } private static int
computaAnosDeContribuicao(double alvo, double contribuição,
double juros) { int anos = 0; double saldo = 0; while (saldo <
alvo) { saldo = (saldo + contribuição) *
(1 + juros); anos++; } return anos; } private static double recebePercentual() { Scanner sc = new Scanner(System.in); if (!sc.hasNextDouble()) { sc.next(); System.out.println("Voce
deve digitar um valor real entre 0 e 1."); return recebePercentual(); } double valor = sc.nextDouble(); if (valor > 1 || valor < 0) { System.out.println("
Voce deve digitar um valor real entre 0 e 1."); return recebePercentual(); } return valor; } private static double recebeDoubleMaiorQue(double minimo) { Scanner sc = new Scanner(System.in); if (!sc.hasNextDouble()) { sc.next(); System.out.println("Voce
deve digitar um valor real maior que "
+ minimo); return recebeDoubleMaiorQue(minimo); } double valor = sc.nextDouble(); if (valor < minimo) { System.out.println("Voce
deve digitar um valor real maior que "
+ minimo); return recebeDoubleMaiorQue(minimo); } return valor; } } |
Vai nos ajudar a lidar com arrays
Java tem arrays unidimensionais e
multidimensionais
Segue um programa que lê 10 números e os imprime em ordem inversa
package p2.exemplos; import java.util.Scanner; /* * Ler 10
números inteiros da entrada, imprimir em ordem inversa * Autor:
Raquel Lopes */ public class Inverte1 { public static void main(String[] args) { Scanner
sc = new Scanner(System.in); int[] números = new int[10]; // criação do array de 10
inteiros for (int i = 0; i < 10; i++) { System.out.print("Entre com o proximo
inteiro: "); números[i]
= sc.nextInt(); } for (int i = 10 - 1; i >= 0; i--) { System.out.print(números[i] + " "); } } } |
O que acharam deste programa?
◦ Será que ele pode ser melhorado?
package p2.exemplos; import java.util.Scanner; /* * Ler 10 números inteiros da entrada, imprimir
em ordem inversa * Autor: Jacques Sauvé */ public class Inverte { public static void main(String[]
args) {
final int NÚMEROS_A_LER = 10; Scanner sc = new Scanner(System.in);
int[] números = new int[NÚMEROS_A_LER];
//
criação do array de 10 inteiros for (int
i = 0; i < números.length; i++) { System.out.print("Entre com o proximo inteiro: "); números[i] = sc.nextInt(); } for (int
i = números.length - 1; i >= 0; i--) { System.out.println(números[i]); } } } |
Observe que arrays são sempre indexados a
partir de zero
Precisa saber o tamanho para criar o array
números.length é o número de elementos
no array números
No laço, é preferível usar números.length a usar o número 10
◦
Por quê?
Segue um programa que ecoa os argumentos de
linha de comando
package p2.exemplos; /* * Ecoar argumentos de linha de comando * Autor: Jacques Sauvé */ public class Eco {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) { System.out.print(args[i]
+ " ");
}
System.out.println();
for (int i = 0; i < args.length; i++) { System.out.println(args[i]);
} } } |
Observe que args é um array normal
composto de Strings
Segue um programa que mostra uma forma de inicializar arrays
package p2.exemplos; /* * Imprime o dia da semana correspondendo ao
argumento de linha de * comando * * Autor: Jacques Sauvé */ public class
Dia { public static void main(String[] args) {
final int DIAS_NA_SEMANA = 7; final String[] diasDaSemana = { "",
"Domingo", "Segunda", "Terca",
"Quarta", "Quinta", "Sexta", "Sabado" }; if (args.length != 1) {
System.err.println("Sintaxe: Dia numero");
System.exit(1);
}
int dia =
Integer.parseInt(args[0]);
if (dia < 1
|| dia > DIAS_NA_SEMANA) { System.err.println("O dia da semana deve estar entre 1 e
" + DIAS_NA_SEMANA); System.exit(1); } System.out.println(diasDaSemana[dia]); } } |
A inicialização do array diaDaSemana já calcula o tamanho necessário
É recomendado usar System.err em vez de System.out para imprimir erros
System.exit(0) é usado para terminar o
programa "bem"
System.exit(1) é usado para terminar o programa
"mal"
Integer.parseInt(xpto) converte o string xpto para um inteiro
Teste: retire o teste que começa com a seguinte linha ...
if (dia < 1 || dia >
DIAS_NA_SEMANA) { |
E veja o que
acontece quando passamos um argumento maior que 7!
Você pode
obter mais informação e dicas sobre entrada e saída em Java aqui
◦ Você poderá não entender tudo que está aí agora, mas volte a ler este material sobre entrada e saída de vez em quando ao longo da disciplina. Você entenderá mais a cada leitura