Você está na página 1de 56

Disciplina: PA1

Bibliografia: 1.Carrio, Jos; Carrio Antnio, Computadores, Tecnologias e sistemas de Informao - O Ncleo de Sistema, Lisboa, 1997, ISBN: 972-96-533-6-4 2.Carrio, Jos; Carrio Antnio, Computadores, Tecnologias e sistemas de Informao - Tecnologias de Software, Lisboa, 1997, ISBN: 972-96-533-8-0 3.Carrio, Jos; Carrio Antnio, Computadores, Tecnologias e sistemas de Informao Perifricos, Internet e multimdia, Lisboa, 1997, ISBN: 972-96-533-7-2 4.Antnio Jos Mendes, Maria Jos Marcelino, Fundamentos de programao em Java 2, FCA, 2002., ISBN 972-722-267-6 5.Elliot Koffman, Ursula Wolz, Problem Solving with Java, 1999, ISBN 0-201-35743-7 6.F. Mrio Martins, Programao Orientada aos objectos em Java 2, FCA, 2000, ISBN 972-722-196-3 7.John Lewis, William Loftus, Java Software Solutions: foundation of program design, 2nd edition, Addision-Wesley, ISBN 0-201-61271-2 8.John R. Hubbard, Theory and problems of programming with Java, Schaums Outline series, McGraw-Hill, ISBN 0-07-134210-9 9.H. Deitel, P. Deitel, Java, como programar, 4 edio, 2003, Bookman, ISBN 85-363-0123-6 10.sites: www.fca.pt, //java.sun.com; 11. www.sun.com; www.javaman.com.br/artigos/JavaComoComecar.html;www.javaworld.com

Introduo ao Programao

[2], pag.42-44

Nossa tarefa no s aprender a Java, mas tambm melhorar sua habilidade no uso de computador como ferramenta para soluo de problemas. Este processo, geralmente chamado de programao, composto de duas tarefas: formular um procedimento logicamente corecto e sem ambiguidades, para resolver um dado problema; traduzir tal procedimento para uma forma aceitvel pelo computador. Um programa de computador , antes de mais nada, um solucionador de problemas. Um modelo de soluo de problemas inclui sete passos a seguir: 1.Deixar claro o problema. 2.Identificar as entradas e sadas. 3.Desenvolver um procedimento para a soluo do problema. 4.Verificar manualmente o procedimento e corrigi-lo, se necessrio. 5.Codificar o algoritmo numa linguagem de programao(LP). 6.Executar o programa com dados de teste, depurando (processo de detectar e remover erros- debugging) quando necessrio. 7.Refinar e documentar o programa. Observamos antes, que a programao consiste em duas tarefas: desenvolvimento de algoritmos e codificao. Um algoritmo uma srie de passos usados para resolver um problema. Voc produz um algoritmo por meio de uma analise sistemtica do problema. O algoritmo expresso em uma linguagem chamada pseudocdigo, que parecida com uma LP, mas que evita detalhes excessivos (semelhante ao ingls). Em seguida, voc codifica, ou seja, traduz o algoritmo para linguagem que computador entenda (Pascal, Fortran, C++, Java ou outra). Para isso voc deve reduzi-lo a uma sequncia de operaes primitivas.

1. Linguagem de programao Java

[2], pag 49-51

A LP Java foi criada nos anos 90 com objectivo de criar uma nova LP que pudesse ser executada em qualquer tipo do computador. Este problema foi resolvido considerando um computador virtual que se imagina capaz de executar um cdigo constitudo por instrues simples. Este cdigo chamado por bytecode, pois usado 1 byte para representar cada instruo.programa Criar O compilador de Java, ao contrrio dos compiladores tradicionais, no vai gerar Editor cdigo executvel, mas sim bytecode. necessrio que cada computador tenha um programa que possa interpretar e executar bytecode. Ao conjunto de todos os intrpretes disponveis dse o nome de mquina virtual Java (JVM- Java Virtual Machine). O esquema seguinte descreve o processo de criao, compilao e execuo de um programa em Java.
Cdigo Java Compilador de Java (JavaC)

Elab. por eng Tatiana Kovalenko

Java bytecode

Interprete de Java

2008

Disciplina: PA1

Para criar programas em Java necessrio ter o Java Development Kit (JDK) instalado no computador. O JDK inclui diversas ferramentas teis, como seja o compilador (chamado javac), o interprete de bytecode (chamado java) e um largo conjunto de classes j programadas com respectiva documentao. Nos sistemas operativos (SO) baseados em janelas comum a utilizao de ambientes integrados de desenvolvimento que facilitam a utilizao do JDK (tais como Kawa, Jel, etc.).

2. Estrutura de um Programa em Java


Um programa em Java um conjunto de uma ou mais classes, uma das quais ser a principal e deve ter o mesmo nome que o ficheiro. Uma classe pode ser vista como um conjunto de variveis e subprogramas(mtodos), sendo que cada um destes ltimos contm instrues que lhes permitem desempenhar uma determinada tarefa. Trs tipos de componentes principais constituem um programa: Declaraes, que reservam a memria para o armazenamento da informao envolvida. Instrues, que definem as aces e decises a tomarem. Comentrios - so teis para os humanos, mas ignorados pelo computador.

2.1. O conjunto de caracteres do Java


A sintaxe do Java, tal como a de outras linguagens, inclui palavras reservadas, smbolos, identificadores e valores. Utilizam-se: as letras de A a Z (maisculas e minsculas), os dgitos 0 a 9, os smbolos especiais: + . < ( : <= ) * ; > [ / >= ] % , == { = ^ != }
palavras reservadas que tm em Java um significado padro e predefinido. Por exemplo,

while, if e new so instrues e class, int e void indicam tipos de informao declarada. Estas palavras reservadas podem ser usadas unicamente para o fim a que so destinadas, no podendo ser arbitrariamente redefinidas pelo programador.

2.2. Identificadores
Um identificador um nome que dado a um elemento do programa, tal como uma constante, varivel, subprograma ou classe. Os identificadores so compostos de letras (somente da lngua inglesa), dgitos, caracteres _ e $ em qualquer ordem, desde que o primeiro caracter no seja um digito. O Java distingue entre maisculas e minsculas, ou seja, Max, max e MAX so considerados identificadores diferentes. comum usar certas convenes para os identificadores: o nome de uma classe comea por maiscula (por ex. Poligono)
Elab. por eng Tatiana Kovalenko
2

2008

Disciplina: PA1

o nome de um subprograma(mtodo) comea por minscula (por ex. main()) o nome de uma varivel comea por minscula (por ex. cateto1) o nome de uma constante todo em maisculas (por ex. MAX) No pode usar palavras reservadas como identificadores. Valido x1 soma a_b $dollar Invalido 1_x M&M Int $dllar

Os valores so dados explcitos que podem ser manipulados pelos programas.

2.3. Variveis
Uma varivel representa uma localizao em memria do computador que tem um nome atribudo pelo programador e que vai servir para guardar informao de um determinado tipo. O valor de uma varivel pode variar durante a execuo de um programa. As variveis so declaradas, em Java, quando se escreve o programa e quando isto feito, especificado um nome e um tipo para varivel. A declarao de variveis obrigatria. A sintaxe da declarao de variveis a seguinte: tipo_de_dado nome_da_variavel; ou tipo_de_dado nome_da_variavel = valor_inicial; A primeira forma declara apenas uma varivel e a segunda, alem de declarar, inicializa a varivel com valor fornecido. Exemplos:
int numConta; int valMax = 1; double preco, total;

2.4. Constantes
Constantes so os dados cujos valores se mantm inalterados ao longo do programa. A sintaxe de declarao de uma constante a seguinte: final tipo_de_dado NOME_DE_CONSTANTE = valor; Exemplo:
final int MAX_STUDENTS = 25;

No pode mudar o valor da constante aps a sua declarao.

2.5. Um primeiro programa em Java


Pretende-se elaborar um programa que, dadas as dimenses dos catetos de um tringulo rectngulo, calcule e fornea ao utilizador o comprimento da hipotenusa. Devemos analisar o problema e elaborar um algoritmo para resoluo deste. O algoritmo pode ser escrito na seguinte forma: 1.Reservar espao na memria para armazenar os valores dos dois catetos e da hipotenusa; 2.Pedir ao utilizador as dimenses dos catetos, ler os valores fornecidos e armazen-los em duas variveis (cateto1 e cateto2); 3.Calcular o resultado e armazen-lo na varivel hipotenusa; 4.Visualizar o resultado. Traduzimos o algoritmo para a linguagem Java:
1. 2. 3. 4. 5. 6. 7. 8. 9. public class Pitagoras { public static void main(String[] args) { //Declarao de variaveis double cateto1, cateto2, hipotenusa; //L dimensoes dos catetos System.out.print("Valor do primeiro cateto: "); cateto1 = Le.umDouble(); System.out.println("Valor do segundo cateto: ");
3

Elab. por eng Tatiana Kovalenko

2008

Disciplina: PA1

10. 11. 12. 13. 14.

cateto2 = Le.umDouble(); hipotenusa = Math.sqrt (cateto1*cateto1 + cateto2*cateto2); System.out.println("Hipotenusa: " + hipotenusa); } //fim do metodo main } //fim da classe Pitagoras

Em linguagens orientadas aos objectos como o Java, o cdigo executvel tem sempre que ser integrado numa classe. A classe uma entidade central em programao orientada aos objectos. 1a linha do programa inicia uma definio de classe para a classe Pitagoras, onde Pitagoras o nome por ns atribudo. Essa classe conhecida como classe definida pelo programador. 2a linha do programa permite identificar o subprograma principal, o main() e, consequentemente, o incio do programa. O bloco de instrues pertencentes ao subprograma main() delimitado por chavetas {}. A linha 2 faz parte de todo aplicativo Java. Os aplicativos Java comeam a execuo por main. Os parnteses depois de main indicam que main um bloco de construo de programa denominado mtodo. As definies de classe de Java normalmente contm um ou mais mtodos. A palavra-chave void indica que esse mtodo realizar uma tarefa, mas no retornar nenhuma informao quando completar sua tarefa. System.out.println() um programa predefinido em Java que permite escrever no ecr a mensagem (ou string) que se encontra entre parnteses. A diferena entre print e println que, depois de exibir seu argumento o cursor de sada no muda de linha. 3 e 6 linhas contm comentrios que comeam por // Na 7a e 9a linhas pede-se ao utilizador a introduo de dimenses dos catetos. Na 8a e 10a linhas feita a leitura dos valores fornecidos pelo utilizador. Le.umDouble() um subprograma que l um valor real do teclado. Os valores introduzidos so armazenados nas variveis cateto1 e cateto2 graas ao operador de atribuio (=). Na 11a linha calcula-se o valor da hipotenusa utilizando outro mtodo Math.sqrt que calcula a raiz quadrada do valor resultante da expresso entre parntesis. 12a linha escreva o resultado de clculo no ecr acompanhado pelo cadeia de caracteres que est entre aspas. Agora o programa pode ser compilado e executado. Para isso dever ser guardado num ficheiro com o mesmo nome (Pitagoras) e extenso .java. Os passos necessrios para compilar e executar o programa dependem do ambiente de desenvolvimento e do SO em que se est a trabalhar.

3. Tipos de dados bsicos (tipos primitivos)


Um tipo de dados definido pela gama de valores que pode representar e pelas operaes que sobre eles se podem efectuar. Java permite tratar oito tipos de dados predefinidos: boolean, char, byte, short, int, long, float e double.

3.1. Representao de nmeros inteiros


A representao de nmeros inteiros assegurada pelos seguintes tipos:
Tipo byte short int long Memria ocupada 8 bits 16 bits 32 bits 64 bits Menor valor -128 -32 768 -2 147 483 648 (-231) -9 233 372 036 854 755 808 (-263) Maior valor 127 32 767 2 147 483 647 (231-1) 9 223 372 036 854 775 807 (263-1)

public class A_mais_B { public static void main(String[] args) { //Declarao de variveis int a, b; long resultado;
Elab. por eng Tatiana Kovalenko
4

2008

Disciplina: PA1

} }

//L valor de A e B System.out.print("Introduza o valor A: "); a = Le.umInt(); System.out.println(a); System.out.print("Introduza o valor B: "); b = Le.umInt(); System.out.println(b); resultado = a+b; System.out.println("A soma entre "+a+ " e "+b+" igual a "+resultado);

Para alem de representao decimal, os nmeros podem tambm ser representados nas bases octal e hexadecimal. Para isso usam-se prefixos: 0 para octal e 0x para hexadecimal. Por exemplo: 0513 (em octal) e 0xa9cd (em hexa)

3.2. Representao de nmeros decimais


A representao de nmeros com parte fraccionria pode ser feita atravs de seguintes tipos: Tipo float double Memria ocupada 32 bits 64 bits Menor valor -3.4 x 1038 -1.7 x 10308 Maior valor 3.4 x 1038 1.7 x 10308

Os valores reais podem ser representados usando a notao decimal (por ex. 34.054) ou a notao exponencial (por ex. 2.5E-6 que representa o nmero 2,5 x 10-6). Em qualquer dos casos, o nmero pode ser seguido das letras f (ou F) ou d (ou D) indicando que se pretende o seu armazenamento como float ou como double. A ausncia de indicao implica que o nmero seja considerado como double.
public class AxB_real { public static void main(String[ ] args) { float a, b; //Declarao de variaveis double resultado; System.out.print("Introduza o valor A: "); a = Le.umFloat(); System.out.println(a); System.out.println("Introduza o valor B: "); b = Le.umFloat(); System.out.println(b); resultado = a*b; System.out.println(a+ " x "+b+" = "+resultado);

} }

3.3. Representao de caracteres


O tipo CHAR usado para guardar caracteres individuais que so representados internamente no computador pelos seus cdigos ASCII. A declarao de variveis deste tipo feita da seguinte forma:
char letra letra = 'M'; ou char letra = 'a';

O uso de caracteres feito entre apstrofos ' '. Por exemplo: Uma vez que as variveis do tipo char armazenam cdigos, que so nmeros, possvel fazer algum tipo de aritmtica com estes variveis, nomeadamente incrementaes e decrementaes. Tipo Memria ocupada Valores char 16 bits Qualquer caracter pertencente ao Unicode Exemplo: Visualizar no ecr um caracter introduzido do teclado
public class Caracter { public static void main(String [] args) { char umCar; //Declarao de variavel

Elab. por eng Tatiana Kovalenko

2008

Disciplina: PA1

System.out.println("Introduza um caracter (p.ex. uma letra): "); umCar = Le.umChar(); //L um caracter do teclado System.out.println("O caracter lido foi " + umCar); } }

3.4. Representao de valores lgicos


O tipo boolean um tipo de dados para guardar valores lgicos, nomeadamente true (verdade) e false (falso). Tipo boolean Memria ocupada 1 bit Valores true ou false

4. Instruo de atribuio
A atribuio permite armazenar um valor numa varivel. Esse valor pode ser fornecido directamente ou resultar do clculo de uma expresso.
public class IntAlunos { public static void main (String args[]) { int alunos = 80; System.out.println("H "+alunos+" alunos no curso"); alunos = 130; //a variavel recebeu um novo valor System.out.println("Agora j h "+alunos+" alunos");

} }

Este programa comea por criar uma varivel inteira denominada alunos, inicializando-a com o valor 80. Em seguida o valor da varivel alunos alterado e passa a conter 130.

5. Expresses
Uma expresso uma sequncia de operadores e de valores. A linguagem Java tem definido um conjunto de operadores, aritmticos e lgicos, que permitem a construo de expresses.

5.1. Expresses aritmticas


Operadores vlidos: Operador * / % + Prioridade 1 1 1 2 2 Operao Multiplicao Diviso Resto da diviso Adio Subtraco

Uma referncia particular para o operador diviso, pois este apresenta comportamentos diferentes em funo do tipo de operandos a que aplicado. No caso de algum dos operandos ser real (float ou double), o resultado ser tambm um nmero real. Por exemplo:
x = 10/4.0; //x 2.5

No entanto, se ambos os operadores forem inteiros (byte, short, int ou long), o resultado ser tambm um inteiro, pelo que a parte fraccionria do resultado desprezada. Assim, y = 10/4; //y 2 O operador % permite calcular o resto de uma diviso. Por exemplo:
z = 13%4; //z 1

Ainda que este operador seja geralmente mais til para calcular o resto de divises inteiras, o Java permite tambm a sua utilizao com operandos reais. Por exemplo:
f = 8.6%2.0; //f 0.6

Exemplo:
public class ConvSegHoras { public static void main(String args[]) { int totalSegs, horas, minutos, segundos, segs; //L o nmero de segundos System.out.print("Numero total de segundos: ");
Elab. por eng Tatiana Kovalenko
6

//por ex. 8500


2008

Disciplina: PA1

totalSegs = Le.umInt(); //Calcula o nmero de horas (diviso inteira por 3600) //Uma hora tem 3600 segundos horas = totalSegs / 3600; //8500/3600=2 //Calcula o nmero de segundos que sobram segs = totalSegs % 3600; //8500%3600=1300

//Calcula o nmero de minutos que existem nesses segundos minutos = segs / 60; //1300/60=21 //Calcula o nmero de segundos que sobram //(resto da diviso anterior) segundos = segs % 60; //1300%60=40 System.out.print(totalSegs+" segundos correspondem a "+horas+" hora(s) "+ minutos+" minuto(s) e "+segundos+" segundo(s)"); } }

A linguagem Java inclui tambm operadores de incrementao e de decrementao unria de variveis, ++ (soma um ao seu operando) e -- (subtrai um ao seu operando) Exemplo: conta++; conta- -; ou ainda: ++conta; - -conta; //ps-incremento //ps-decremento //pr-incremento //pre-decrimento

A distino entre as duas formas destes operadores, antes ou depois do operando, s relevante quando fazem parte de uma expresso maior. Por exemplo, supondo que a varivel num tem o valor 7, a expresso
x = ++num;

incrementa o valor de num (para 8) e depois atribui-o a x (por isso x passa a ter o valor 8). No entanto, se for utilizada a expresso
x = num++;

primeiro feita a atribuio de num a x (x fica com o valor 7) e s depois que feita a incrementao de num.
public class Increment { public static void main( String args[] ) { int c; c = 5; System.out.println( c ); // visualiza 5 System.out.println( c++ ); // visualiza 5 e depois incrementa c System.out.println( c ); // visualiza 6 System.out.println(); // salta uma linha c = 5; System.out.println( c ); // visualiza 5 System.out.println( ++c ); // incrementa c e depois visualiza 6 System.out.println( c ); // visualiza 6

} }

importante notar que, ao incrementar ou decrementar uma varivel em uma instruo isolada, as formas de pr-incremento e de ps-incremento tm o mesmo efeito e as formas de pr-decremento e ps-decremento tm o mesmo efeito. Java fornece vrios operadores de atribuio (+=, -=, *=, /=) para abreviar expresses de atribuio. Por exemplo, podemos abreviar a instruo c = c+3; como c += 3; O operador += adiciona o valor da expresso direita do operador ao valor da varivel esquerda do operador, e armazena o resultado na varivel esquerda do operador. Suponha: int c = 3, d = 5, e = 4, f = 6;
Elab. por eng Tatiana Kovalenko
7

2008

Disciplina: PA1

Operador de += -= *= /=

Expresso de c d e f += -= *= /= 7 4 5 3

Explicao c d e f = = = = c+7 d-4 e*5 f/3

Atribui 10 a c 1 a d 20 a e 2 a f

5.2. Classe Math


O JDK (Java Development Kit) inclui um largo conjunto de classes e mtodos que podem ser utilizados para variados fins. Os mtodos (ou subprogramas) pr-programados da classe Math permitem realizar certos clculos matemticos comuns. Por exemplo, Math.sqrt() calcula a raiz quadrada, Math.pow() calcula a potncia de um nmero elevado ao outro, Math.random() gere um nmero aleatrio entre 0 e 1, Math.sin() calcula o seno de um ngulo. aconselhvel a consulta da documentao do JDK para obter uma lista completa de subprogramas existentes no Math. Exemplo: Calcular o valor de baseexpoente para valores introduzidos do teclado.
public class BaseExp { public static void main(String[ ] args) { int base, expoente; //Declarao de variaveis double resultado; System.out.print("Valor de Base: "); base = Le.umInt(); System.out.print("Valor de Expoente: "); expoente = Le.umInt(); resultado = Math.pow(base, expoente); System.out.print("O valor "+base+ " elevado a "+expoente+" e igual a " +resultado); } }

5.3. Converses de tipo


O tipo do resultado de uma expresso aritmtica depende do tipo dos seus operandos. Se todos eles forem do mesmo tipo, o resultado ser tambm desse tipo. No caso contrrio devem ser feitas as converses de tipo. Algumas so feitas automaticamente e de modo a que no haja perda de informao, pelo que nem todas as transformaes so possveis. Por exemplo, um valor real no pode ser convertido automaticamente para um tipo inteiro, porque isso implicaria a perda de parte decimal do nmero. A cadeia de converso automtica do compilador a seguinte:
byte > short > int > long > float > double

Assim, possvel converter um int em long ou float, mas no possvel converter um double em float ou long sem perda de informao Considere-se o seguinte exemplo:
1. 2. 3. 4. 5. int var_int = 10, resultado_int; double var_double = 5.2, resultado_double; resultado_double = var_int + var_double; resultado_int = var_int + var_double;

Na primeira operao (linha 4) o valor de var_int convertido para double, a soma efectuada e o resultado 15.2 (double) armazenado na varivel resultado_double (double). Na instruo a seguir (linha 5) o compilador vai detectar o erro de incompatibilidade de tipo. A converso do tipos com perda de informao permitida nalguns casos, mas o programador tem que indicar explicitamente que a pretende (este mecanismo chama-se cast). A instruo da linha 5 poderia ser alterada para:
5. resultado_int = (int) (var_int + var_double);

Neste caso o resultado final 15 que vai ser armazenado na varivel resultado_int.
Elab. por eng Tatiana Kovalenko
8

2008

Disciplina: PA1

5.4. Expresses lgicas


Para alm dos operadores aritmticos, a linguagem Java possui tambm operadores relacionais e operadores lgicos. Estes operadores permitem a construo de expresses que tm como resultado um valor lgico, true ou false. Operadores relacionais: >, <, >=, <=, == (igual a), != (diferente de) Operadores lgicos: && (conjuno), | | (disjuno), ! (negao) O operador && tem dois operandos e devolve true apenas se ambos os operadores forem true, caso contrrio devolve false. A B A && B A||B F F F F F T F T T F F T T T T T A operao de negao recebe apenas um operando lgico e inverte o seu valor. A !A F T T F comum que os operandos utilizados pelos operadores lgicos resultem de expresses que envolvem operadores relacionais. A expresso (10 > 5 && 4 != 3) tem como resultado true.

6. Entrada e sada de dados


Os conceitos de entrada e sada de dados so cruciais em programao. As instrues de entrada servem para obter valores do exterior do programa, por exemplo, do teclado. medida que o computador executa um programa os dados que vo sendo introduzidos so atribudos a certas variveis desse programa. Isto permite que um mesmo programa possa fazer clculos para diferentes valores de entrada sem que se altere o programa propriamente dito. Quando um computador executa um programa, chegar a resultados e que o utilizador desejar visualizar. Para isso so necessrios instrues de sada de dados,

6.1. Procedimentos de entrada (input)


A linguagem de Java foi concebida essencialmente para o desenvolvimento de aplicaes para execuo em ambientes grficos, onde a entrada de dados assegurada por dilogos especializados. A leitura de dados a partir do teclado em Java demasiado complicada para ser apresentada numa fase introdutria da aprendizagem da programao. A linguagem Java suporta a entrada de dados em ambientes no grficos atravs da biblioteca System.in. Esta inclui um subprograma, System.in.read(), capaz de ler um caracter a partir do teclado. No entanto, se o dado a fornecer pelo utilizador for composto por mais do que um caracter, este programa revela-se de difcil utilizao. Tendo em conta esta dificuldade, optou-se por propor ao leitor a utilizao de um conjunto de subprogramas capazes de ler dados a partir da entrada padro. A leitura s terminada quando o utilizador pressiona a tecla <Enter>. Estes subprogramas encontram-se agrupados no ficheiro Le.java, onde existe um subprograma para cada tipo de dado simples:
import java.io.*; import java.awt.*; import java.awt.event.*; //Classe para ler dados de entrada (pela entrada padrao //@autor: Paulo Marques (pmarques@dei.uc.pt) public class Le { private static final int BUF_SIZE=1024; //Inibe o construtor por defeito private Le() { }

Elab. por eng Tatiana Kovalenko

2008

Disciplina: PA1

//Le um inteiro da entrada padrao. A entrada terminada com um ENTER. //Se a entrada nao for valida mostrada a mensagem "!!!Nao um inteiro!!!" //e o utilizador pode tentar de novo. @devolve o numero lido public static int umInt() { while(true) { try { return Integer.valueOf(umaString().trim()).intValue(); } catch(Exception e ) { System.out.println("!!! Nao um inteiro !!!");} } } //Le um double da entrada padrao. A entrada terminada com um ENTER. //Se a entrada nao for valida mostrada a mensagem "!!!Nao um double!!!" //e o utilizador pode tentar de novo. @devolve o numero lido public static double umDouble() { while(true) { try { return Double.valueOf(umaString().trim()).doubleValue(); } catch(Exception e ) { System.out.println("!!! Nao um double !!!");} } } //Le um float da entrada padrao. A entrada terminada com um ENTER. //Se a entrada nao for valida mostrada a mensagem "!!!Nao um float!!!" //e o utilizador pode tentar de novo. @devolve o numero lido public static float umFloat() { while(true) { try { return Float.valueOf(umaString().trim()).floatValue(); } catch(Exception e ) { System.out.println("!!! Nao um float !!!"); } } } //Le um String da entrada padrao. A entrada terminada com um ENTER. //Se a entrada nao for valida mostrada a mensagem "!!!Nao uma string!!!" //e o utilizador pode tentar de novo. @devolve o numero lido public static String umaString() { String s = ""; try { BufferedReader in = new BufferedReader (new InputStreamReader(System.in),1); s = in.readLine(); } catch(Exception e) {System.out.println("Error reading from the input stream"); } return s; } }

O ficheiro deve ser copiado para o directrio de trabalho. A utilizao de qualquer um destes subprogramas bastante simples. Por exemplo, para ler um valor double, basta fazer:
cateto1 = Le.umDouble();

Le.umDouble() um subprograma que leva o programa a parar e a esperar que o utilizador escreva um valor real usando o teclado e o confirme coma a tecla <Enter>. O valor introduzido depois armazenado na varivel cateto1 graas ao operador de atribuio (=). Visto que a execuo de qualquer destes subprogramas de leitura suspende a execuo do programa, aconselhvel fazer preceder a instruo de leitura de uma instruo de escrita que indique ao utilizador o que deve fazer.

6.2. Procedimentos de sada


A escrita para o ecr pode ser feita utilizando os mtodos (subprogramas) print ou println existentes na System.out, que conhecido como objecto de sada padro. Qualquer um destes subprogramas permite escrever no ecr, diferindo apenas no facto de o println efectuar uma mudana de linha aps a escrita, o que no acontece com o print.

Elab. por eng Tatiana Kovalenko

10

2008

Disciplina: PA1

Para que possa ser escrita uma mensagem no ecr, estes subprogramas devem receber como parmetro (argumento) a mensagem a escrever, ou seja, esta deve aparecer entre parnteses e imediatamente a seguir ao nome do subprograma. Na sua forma mais simples, a mensagem a escrever uma cadeia de caracteres e deve ser colocada entre aspas. Por exemplo, a instruo:
System.out.print ("Bom dia! ");

escreve no ecr:
Bom dia!

Este mesmo subprograma pode ser utilizado para escrever o valor corrente da varivel. Por exemplo:
int dias = 30; Sytem.out.print (dias);

escreve no ecr:
30

Tambm possvel escrever vrios elementos de uma s vez. Para isso usa-se o operador de concatenao +. Por exemplo:
int dias = 30; System.out.print ("Este ms tem "+dias+" dias");

escreve:
Este ms tem 30 dias

ainda possvel colocar expresses na lista de elementos a escrever. Neste caso a expresso calculada antes de escrita, embora o resultado desse clculo no seja armazenado em memria. Por exemplo:
int int1 = 10, int2 = 4; System.out.print (int1+" menos "+int2+" igual a "+int1-int2);

escrever:
10 menos 4 igual a 6

Mas deve ter cuidado especial no caso se a expresso incluir uma ou mais adies. Por exemplo, se no exemplo anterior substituirmos a subtraco por uma adio, vir:
int int1 = 10, int2 = 4; System.out.print (int1+" mais "+int2+" igual a "+int1+int2);

o que resultar na escrita de :


10 mais 4 igual a 104

Esta ambiguidade pode ser resolvida com a utilizao de parnteses:


int int1 = 10, int2 = 4; System.out.print (int1+" mais "+"int2+" igual a "+(int1+int2));

que resulta em :
10 mais 4 igual a 14

6.2.1. Exibindo uma nica linha de texto com mltiplas instrues As instrues:
System.out.print ("S sei "); System.out.println ("que nada sei");

resultam na escrita de:


S sei que nada sei

6.2.2. Exibindo linhas mltiplas de texto com nica instruo A instruo:


System.out.println ("S\nsei\n\tque\n\t\tnada\n\t\t\tsei!");

resulta em:
S sei que nada sei!
11

Elab. por eng Tatiana Kovalenko

2008

Disciplina: PA1

Caracteres especiais: \n \t \r \\ \ nova linha tabulao horizontal retorno para o incio da linha actual. barra invertida, serve para visualizar no ecr um caractere barra invertida aspas duplas, serve para visualizar no ecr aspas duplas

7. Seleco
comum que, durante a execuo de um programa, seja necessrio tomar decises em funo de valores fornecidos pelo utilizador ou de resultados previamente calculados. Este tipo de decises representado por estruturas a que se d o nome de estruturas de seleco. O Java apresenta trs variantes desta estrutura: seleco simples, seleco em alternativa e seleco mltipla.

7.1. Seleco simples. Instruo if


A seleco simples permite decidir entre executar ou no um conjunto de instrues. A deciso tomada em funo do resultado de uma condio, ou seja, uma expresso com resultado lgico, que calculada no incio da execuo da estrutura. O funcionamento deste tipo de estrutura pode ser representado pelo seguinte fluxograma: V F
I

Como se pode observar, no incio avaliado o valor lgico da condio. Se o resultado for verdadeiro, as instrues (I) sero executadas, prosseguindo depois o programa para a execuo da instruo seguinte. Se o resultado for falso, as instrues no sero executadas, prosseguindo o programa de imediato para a instruo seguinte. A instruo de deciso if tem a seguinte sintaxe: if (condio) { instrues; } Repare-se que as chavetas delimitam as instrues a executar no caso do resultado da condio ser true. As instrues so executadas se a condio for verdadeira. Caso seja necessrio executar uma s instruo para uma condio verdadeira, as chavetas podem ser omitidas: if (condio) instruo; Exemplo: Visualizar na ordem crescente dois nmeros inteiros fornecidos pelo utilizador. O algoritmo comea por ler dois nmeros fornecidos pelo utilizador, depois verifica se o primeiro nmero introduzido maior do que o segundo e, em caso afirmativo, troca os valores. No caso de o primeiro nmero ser menor, no feita a troca.
public class Troca { public static void main (String args []) { int num1, num2, temp; System.out.println("Introduza o primeiro numero: "); num1 = Le.umInt(); System.out.println("Introduza o segundo numero: "); num2 = Le.umInt();
Elab. por eng Tatiana Kovalenko
12

2008

Disciplina: PA1

} }

if (num1 > num2) { temp = num1; num1 = num2; num2 = temp; } System.out.println ("Numeros na ordem crescente: "+num1+" , "+num2);

Um erro comum a colocao de um ; imediatamente a seguir ao if. Por exemplo:


if (v1>v2); System.out.print ("Maior= "+v1);

O ponto e vrgula interpretado pelo compilador de Java como uma instruo vazia, pelo que utilizada para separar instrues. Deste modo, se v1 for maior que v2, vai ser executada a instruo ; cujo efeito nulo. A instruo System.out.print("Maior= "+v1); vai ser sempre executada, mesmo que v1 no seja maior do que v2. Neste caso o compilador no pode detectar o erro.

7.2. Seleco em alternativa. Instruo if-else


A segunda verso de instruo if corresponde a uma estrutura de deciso com alternativa dupla. Muitas vezes interessa escolher de entre dois conjuntos de instrues qual deles deve ser executado. Esta escolha tambm ser feita em funo do resultado de uma condio. Graficamente: V
I1 ?

F
I2

A sintaxe de estrutura de deciso com alternativa dupla:


if (condio) { conjunto de instrues1 se condio for verdadeira; } else { conjunto de instrues2 se condio for falsa; }

O conjunto de instrues1 seja executado se a condio for verdadeira. Se a condio for falsa, ser executado o conjunto de instrues2. Exemplo: Visualizar uma mensagem se o valor introduzido for par ou mpar.
public class SeraParOuImpar { public static void main(String args[]) { int num; System.out.println("Escreva um numero: "); num = Le.umInt(); //Le o numero if (num % 2 == 0) System.out.println("O numero "+num+" par"); else System.out.println("O numero "+num+" impar"); } }

Claro que em cada execuo do programa, e dependendo do valor introduzido pelo utilizador, apenas uma destas instrues ser executada. Neste exemplo foi utilizada uma instruo if-else para seleccionar uma de duas alternativas. No entanto, h situaes em que h mais do que duas alternativas, de entre as quais
Elab. por eng Tatiana Kovalenko
13

2008

Disciplina: PA1

necessrio escolher uma delas. Neste caso as instrues if-else podem ser encadeadas de forma a possibilitar vrias alternativas, como por exemplo:
if (condioA) { conjunto de instrues1 se condioA for verdadeira; } else if (condioB) { conjunto de instrues2 se condioB for verdadeira; } else { conjunto de instrues3 se condioB for falsa; }

Teoricamente no existe um limite para o encadeamento destas instrues. Tal como no caso da seleco simples, tambm no caso da seleco em alternativa se podem omitir as chavetas quando est em causa apenas a execuo de uma instruo. Exemplo: Calcular e visualizar o valor de Y
y= a>300 V ab+c V ab+c
_________

ab+c ab+c (a:c+b)2

, se a>300 , se a=300 , se a<300

F a=300 F (a:c+b)2

public class IfEncad { public static void main(String args[]) { double a, b, c, y; System.out.print ("Intr. o valor de A: "); a = Le.umDouble(); System.out.println(a); System.out.print("Intr. o valor de B: "); b = Le.umDouble(); System.out.println(b); System.out.print("Intr. o valor de C: "); c = Le.umDouble(); System.out.println(c); if (a > 300) y = a*b+c; else if (a == 300) y = Math.sqrt(a*b+c); else y = (a/c+b)*(a/c+b); System.out.println("O valor de Y= " + y); } }

Se a estrutura de deciso envolver apenas seleco em alternativa, fcil ver a que if pertence cada else, uma vez que cada um deles pertence ao if mais prximo que no tenha else. Quando o encadeamento inclui seleces simples e seleces em alternativa pode no ser to fcil perceber a que if pertence um dado else. Considere, por exemplo, a seguinte arvore de deciso:
condio1 V condio2 V condio3 V F
Elab. por eng Tatiana Kovalenko
14

F instr.C

2008

Disciplina: PA1

instr.A

instr.B

Se a condio2 for falsa, no se pretende executar qualquer instruo, pelo que esta uma seleco simples. Esta rvore de deciso pode ser implementada em Java:
if (condio1) if (condio2) if (condio3) instruoA; else instruoB; else instruoC;

Existem casos quando necessrio trabalhar com o relacionamento de duas ou mais condies ao mesmo tempo na mesma instruo, efectuando desta forma testes mltiplos. Exemplo. Ler 3 valores para os lados de um tringulo. Verificar se os valores fornecidos formam realmente um tringulo. Se for esta condio verdadeira, deve ser indicado qual tipo de tringulo foi formado: issceles, escaleno ou equiltero.
public class DeterminarTriangulo { public static void main(String args[]) { float a,b,c; System.out.println("Informe o 1 lado de triangulo: "); a = Le.umFloat(); System.out.println("Informe o 2 lado de triangulo: "); b = Le.umFloat(); System.out.println("Informe o 3 lado de triangulo: "); c = Le.umFloat(); if (a+b>c && b+c>a && a+c>b) if (a==b && b==c) //caso a=b=c System.out.println("Triangulo Equilatero"); else if (a==b || b==c || a==c) //caso a=b ou b=c ou a=c System.out.println("Triangulo Isosceles"); else System.out.println("Triangulo Escaleno"); //todos os lados difer. else System.out.println("Os valores fornecidos nao formam um triangulo"); } }

7.3. Seleco mltipla. Instruo switch - case


Se a escolha for feita em funo do valor de uma expresso inteira ou caracter, mais eficaz utilizar uma estrutura de seleco mltipla para o mesmo efeito. Graficamente:
V1 ? I1 I2 V2 . . . . Vn outro

. . .

In

Id

Esta estrutura comea por calcular o valor da expresso que ter que ter resultado inteiro (byte, short, int ou long) ou caracter (char). Se algum dos valores V1 a Vn for igual ao resultado da expresso, as instrues correspondentes sero executadas. Sintaxe de instruo switch-case:
switch { case case case (expresso ou varivel) valor1 : instrues1; break; valor2 : instrues2; break; valorN : instruesN; break;
15

Elab. por eng Tatiana Kovalenko

2008

Disciplina: PA1

default

: instruesDefault; break;

} A instruo case controlada pela varivel ou expresso colocada a seguir palavra case e, de acordo com o seu valor, executa um determinado conjunto de instrues. A instruo break utilizada para promover o desvio da execuo para a linha posterior ao final de seu bloco. Exemplo: Escrever um programa que permite calcular reas das diferentes figuras geomtricas.
public class AreasSwitch { public static void main(String args[]) { double a,b,h,area; char letra; System.out.print("Quer calcular area de Triangulo(T), "); System.out.println("Rectangulo(R), Trapezio(Z) ou Circulo(C)? "); letra = Le.umChar(); switch (letra) { case 'R' | 'r': //pode utilizar OR lgico (|),mas no OR dinmico (||) System.out.println("Introduza o valor da base: "); b = Le.umDouble(); System.out.println("Introduza o valor da altura: "); h = Le.umDouble(); area = b*h System.out.println("Area do rectangulo= "+ area); break; case 'T' : //essa a outra forma de permitir o uso de 'T' e 't' case 't' : System.out.println("Introduza o valor da base: "); b = Le.umDouble(); System.out.println("Introduza o valor da altura: "); h = Le.umDouble(); System.out.println("Area do triangulo= "+ b*h/2); break; case 'C' | 'c': System.out.println("Introduza o valor do raio: "); b = Le.umDouble(); area = Math.PI*b*b; System.out.println("Area do circulo= "+ area); break; case 'Z' | 'z': System.out.println("Introduza o valor da 1a base: "); a = Le.umDouble(); System.out.println("Introduza o valor da 2a base: "); b = Le.umDouble(); System.out.println("Introduza o valor da altura: "); h = Le.umDouble(); System.out.println("Area do trapezio= "+(a+b)/2*h); break; default : System.out.println("Introduziu a letra errada"); break; } } }

8. Repetio
Em todos os programas que encontrmos at agora, cada instruo era executada uma nica vez, pela mesma ordem em que aparecia no programa. No entanto, a maioria dos programas que tm interesse prtico incluem estruturas repetitivas. Por exemplo, no caso de se pretender criar uma pequena agenda de telefones, seria necessrio ler dados de cada pessoa (nome, morada e nmero de telefone). Isto poderia ser feito atravs de trs instrues de leitura. Se pretender ler dados das 30 pessoas, 90 instrues de leitura sero necessrias. A situao poderia ser ainda mais complicada se o nmero de pessoas no fosse conhecido partida. Uma forma eficaz de resolver este problema a utilizao de uma estrutura que se encarregue de fazer repetir as instrues que permitem ler os dados de uma
Elab. por eng Tatiana Kovalenko
16

2008

Disciplina: PA1

pessoa tantas vezes quantas as pessoas envolvidas. Estas estruturas so denominadas por estruturas repetitivas ou ciclos.

8.1. Ciclo while


Quando no sabemos quantas vezes deve se fazer a repetio utilizam-se os ciclos while e do...while. O critrio de execuo ou paragem destes ciclos depende de uma condio, que ser testada antes ou depois de cada execuo de ciclo. O ciclo while faz o teste primeiro e executa as instrues depois, caso a condio for verdadeira.

F V

Como se pode observar, o primeiro passo o clculo da condio. Se o resultado for verdadeiro, as instrues (I) so executadas, seguindo-se um novo clculo da condio. Se esta se mantiver verdadeira, as instrues so de novo executadas e a condio calculada. Quando a condio tiver resultado falso, o ciclo terminar, prosseguindo a execuo do programa na instruo seguinte ao ciclo. Sintaxe da instruo while:
inicializao; while (condio) { instrues; aco; } //da varivel que controla a quantidade de repeties //executadas apenas enquanto condio for verdadeira //incrementao ou decrem. da varivel de controle

Exemplo: Calcular a mdia de N nmeros inteiros positivos fornecidos pelo utilizador.


public class MediaN_Numeros1 { public static void main (String args[]) { //Declarao de variveis float media, soma = 0; int quant, num; int contador = 0; //inicializao da varivel de controle de repeties System.out.println("Quantos numeros pretende introduzir? "); quant = Le.umInt(); while (contador < quant) { System.out.println("Intr. proximo numero: "); num = Le.umInt(); soma += num; contador ++; //aco, i.e. incrementao da varivel de controle } media = soma / quant; System.out.println("A media dos "+quant+" numeros = "+media); } }

Note-se que, devido ao facto de a condio boleana ser testada antes, o conjunto de instrues pode nunca vir a ser executado. Isto acontece se o resultado da condio for false logo no incio.

Elab. por eng Tatiana Kovalenko

17

2008

Disciplina: PA1

Um cuidado muito importante que o programador deve ter ao programar um ciclo criar as condies para que o mesmo possa terminar. Para isso, entre as instrues a repetir ter que haver pelo menos uma que, numa dada circunstncia, altere o valor de uma ou mais das variveis que integram a condio que controla o ciclo, por forma a que a mesma passe a ter resultado false e, consequentemente, o ciclo possa terminar.

8.2. Ciclo do...while


Ao contrrio do ciclo while, o ciclo do...while primeiro executa as instrues e depois faz o teste. Caso a condio for verdadeira o ciclo repete-se. A instruo do...while comanda um conjunto de outras instrues at que, uma determinada condio seja verdadeira:

Sintaxe da instruo do...while:


inicializao; do { intrues; aco; } while (condio);

I V F

Notar que, devido ao facto de a condio apenas ser testada no fim, o conjunto de instrues executado pelo menos uma vez. O exemplo anterior pode ser feito com a utilizao do ciclo do...while:
public class MediaN_Numeros2 { public static void main (String args[]) { float media, soma = 0; int quant, num; int contador = 0; //inicializao da varivel de controle de repeties System.out.println("Quantos numeros pretende introduzir (>0) ? "); quant = Le.umInt(); do { System.out.println("Intr. proximo numero: "); num = Le.umInt(); soma += num; contador ++; //aco, i.e. incrementao da varivel de controle } while(contador < quant); media = soma / quant; System.out.println("A media dos "+quant+" numeros = "+ media);

} }

Uma das utilizaes mais comuns deste tipo de repetio a validao de dados fornecidos pelo utilizador. Exemplo: Pretende se introduzir numero de horas trabalhadas, sabendo que os valores podem variar de 0 a 12. No caso contrrio deve aparecer um aviso de erro e pedido de repetir a entrada do valor.
public class ValidarHorasTrab { public static void main (String args []) { byte h; do { System.out.print("Intr. a quantidade de horas trabalhadas: "); h = Le.umByte(); if (h < 0 || h > 12) System.out.println("Numero introduzido invalido! Tente de novo!"); } while (h < 0 || h > 12); System.out.println("Horas trabalhadas: "+ h); }
Elab. por eng Tatiana Kovalenko
18

2008

Disciplina: PA1

J podemos elaborar um menu que permite escolher uma ou mais opes ou terminar o programa.
public class MenuSimples { public static void main (String args[]) { int op; do // Repete at escolher opo 3 (sair) { do { System.out.println ("Qual a tua opo? "); System.out.println ("1 - Mensagem de boas vindas"); System.out.println ("2 Ler valor"); System.out.println ("3 - Sair"); op = Le.umInt (); } while (op < 1 || op > 3); switch (op) { case 1: System.out.println (); System.out.println ("Ola! Bem vindo!"); System.out.println (); break; case 2: System.out.println ("Intr.um valor inteiro: "); int n = Le.umInt(); System.out.println ("O valor introduzido = " + n); break; } } while (op != 3); } }

8.3. Ciclo for


O ciclo for uma estrutura de repetio compacta. Seus elementos de inicializao, condio e aco so reunidos em forma de um cabealho. Quando se pretende que um conjunto de instrues se repita um nmero de vezes bem especfico, utiliza-se o ciclo for, cuja sintaxe seguinte:
for (inicializao; condio; aco) { instrues; }

O funcionamento desta instruo controlado pela inicializao, pela condio e pela aco. Estas trs componentes so separadas por um ponto e vrgula, enquanto que a condio uma expresso com resultado lgico. Estas trs componentes tm a seguinte funo na dinmica da repetio: inicializao executada apenas uma vez logo no incio do ciclo. Serve normalmente para inicializar a varivel que vai controlar o nmero de vezes que as instrues vo ser repetidas; condio calculada antes de cada execuo das instrues. Se o seu resultado for verdadeiro, as instrues so executadas, se for falso, o ciclo termina; aco executada automaticamente em cada iterao aps as instrues do ciclo. Normalmente serve para calcular o novo valor da varivel de controlo (usualmente a aco uma incrementao ou decrementao da varivel de controlo). Pr-incrementar e ps incrementar tem o mesmo efeito na expresso de incremento. Exemplos com a estrutura for: 1). a varivel de controle varia de 1 a 100 em incrementos de 1:
for (int i = 1; i <= 100; i++)

2). a varivel de controlo varia de 20 a 2 em incrementos de 2 (ou decrementos de 2):


for (int i = 20; i >= 2; i-=2)

3). permite somar todos os inteiros pares de 2 a 100:


for (int num = 2; num <= 100; num+=2) sum += num;

As duas ltimas instrues podem ser escritas na forma mais compacta:


Elab. por eng Tatiana Kovalenko
19

2008

Disciplina: PA1

for (int num = 2; num <= 100; sum += num, num+=2) ;

Esta ltima verso exemplifica uma situao em que a componente aco contm mais do que uma instruo, separados por vrgulas. Neste exemplo, com a incluso da instruo a repetir na componente aco, o conjunto de instrues a repetir fica vazio, pelo que a seguir ao for aparece um ; (instruo vazia). Mas aconselhvel evitar esta forma pois torna o programa mais difcil de ler. Apesar de ser usual declarar as variveis no incio, estas podem de facto ser colocadas em qualquer ponto do programa. Exemplo: Escreve o programa que visualiza no ecr todos os nmeros inteiros entre 1 e um nmero positivo fornecido pelo utilizador. Algoritmo:
Pedir o nmero ao utilizador Ler o nmero para a varivel num Para todos os valores de k entre 1 e num escreve k Fim_Para

Para traduzir este algoritmo para Java, necessrio utilizar um ciclo que se repita num vezes e em que a varivel k deve assumir o valor 1 na primeira iterao, o valor 2 na segunda e assim sucessivamente, at assumir o valor de num na ltima iterao. Este comportamento pode ser obtido atravs da utilizao da instruo for.
public class VisualizarInteiros { public static void main (String args []) { int num, k; System.out.prntln("O programa visualizar nmeros de 1 um valor escolhido por si! "); //validao do numero introduzido do { System.out.println("Intr. at que nmero pretende ter a lista: "); num = Le.umInt(); if (num <= 1) System.out.println("Numero deve ser maior que 1!Tente de novo"); } while (num <= 1); System.out.println("Numeros entre 1 e "+num+" : "); for (k = 1; k <= num; k++) System.out.print(k+" "); } }

Na maioria dos casos, a estrutura for pode ser representada por uma estrutura while equivalente:
inicializao; while (condio) { instrues; aco; }

8.4. Ciclos for um dentro de outro


Por exemplo, para aceder aos elementos duma matriz bidimensional deve se utilizar dois ciclos for, um dentro do outro. O primeiro serve para fazer variar linhas e o segundo para fazer variar colunas. Mais tarde vamos aprender esta tcnica. Um outro exemplo pode ser seguinte: visualizar no ecr uma tabela de multiplicao organizada em linhas e colunas:
public class ForForTabMult { public static void main (String args []) { final int SIZE = 12; for ( int x=1; x<=SIZE; x++) { for ( int y=1; y<=SIZE; y++) { int z = x*y;
Elab. por eng Tatiana Kovalenko
20

2008

Disciplina: PA1

if (z<10) System.out.print(" "); if (z<100) System.out.print(" "); System.out.print(" "+ z); } System.out.println(); }
1 2 3

} O output ser:
2 4 6 3 6 9

4 8 12 . . . . . . . . . 9 18 27 36 10 20 30 40 11 22 33 44 12 24 36 48

5 10 15 . . 45 50 55 60

6 12 18 . . 54 60 66 72

7 14 21 . . 63 70 77 84

8 9 10 11 12 16 18 20 22 24 24 27 30 33 36 . . . . . . . . . . 72 81 90 99 108 80 90 100 110 120 88 99 110 121 132 96 108 120 132 144

8.5. Como escolher entre as instrues de repetio


Os trs tipos de controlo de repetio devem ser usados visando s seguintes caractersticas: for Utiliza-se no caso de saber o nmero de repeties antecipadamente. No entanto, dada a flexibilidade com que foi implementado na linguagem Java (tal como em C), esta instruo pode ser utilizada em situaes em que a repetio seja controlada por uma condio, sem que o nmero de repeties seja conhecido partida. do...while Controla a condio de repetio aps a sua execuo. O ciclo executado pelo menos uma vez. Assim, s faz sentido utiliz-lo em situaes em que este comportamento seja desejvel. Um exemplo tpico a validao de dados fornecidos pelo utilizador, pois estes tm que ser lidos antes de ser possvel valid-los. while Controla a condio de repetio antes da sua execuo. O ciclo pode nunca ser executado. Como j foi referido o ciclo for pode tambm ser utilizado nestas situaes, mas a utilizao do while tende a produzir cdigo mais claro e mais legvel.

9. Mdulos de programas em Java


A experincia mostra que a melhor maneira de desenvolver e manter um programa grande constru-lo a partir de pedaos pequenos e simples, chamados de mdulos ou subprogramas. Cada um deles resolve um aspecto particular do problema. Principais vantagens de uso de mdulos (em outras LP chamados funes, procedimentos, subrotinas e subprogramas) so: 1.lidar com a complexidade; 2.encurtar os programas; 3.tornar programas mais claras e legveis; 4.facilitar a correco dos erros; 5.tornar os programas mais eficazes. Os mdulos em Java so chamados de mtodos e classes. Os programas em Java so escritos combinando-se novos mtodos e classes que o programador escreve com mtodos e classes pr-empacotados disponveis na Java API (biblioteca de classes Java) e em vrias outras bibliotecas de mtodos e classes. A Java API fornece uma rica coleco de classes e mtodos para realizar clculos matemticos comuns, manipulaes de caracteres, operaes de entrada/sada e muitas outras operaes teis. Os mtodos da Java API so fornecidos como parte do Java Developers Kit (J2SDK). 9.1. Chamada de um mtodo. Parmetros A chamada de um mtodo (subprograma) feita atravs do seu nome (identificador) seguido por parnteses() contendo (ou no) uma lista de parmetros reais (ou argumentos) de que o mtodo necessita para funcionar. Existe uma relao de nmero, de ordem e de tipo entre os parmetros reais e parmetros formais (aqueles que encontram-se dentro de mtodo). Quando a chamada de mtodo termina, o mtodo ou devolve um resultado para o mtodo que chamou ou simplesmente devolve o controle para o mtodo que chamou. Se o mtodo estiver em uma outra classe, a chamada deve ser precedida por um nome de referncia e um operador ponto. Mas se estiver em mesma classe, pode chamar os outros
Elab. por eng Tatiana Kovalenko
21

2008

Disciplina: PA1

mtodos directamente. Entretanto, existe uma excepo a esta regra. Os mtodos static de uma classe somente podem chamar outros mtodos static da classe directamente. Exemplos de chamdada de mtodos:
drawLine (0,0,20,20); resultado = Math.pow(2,3);

O mtodo Math.pow chamado de forma diferente do drawLine. Enquanto que a chamada do mtodo drawLine() uma instruo autnoma, a chamada do Math.pow() aparece integrada numa instruo de atribuio. Isto acontece porque este ltimo tem um valor de retorno (o resultado do clculo da potncia 23), enquanto que o mtodo drawLine() se limita a desenhar a linha sem devolver qualquer valor. Concluso: quando um mtodo (subprograma) tem valor de retorno, a sua chamada tem que ser integrada numa instruo, para que o valor devolvido possa ser utilizado. Os parmetros de um mtodo podem ser constantes, variveis ou expresses. Por exemplo:
System.out.println (Math.sqrt(c+d*f));

9.2. Os mtodos da classe Math Os mtodos da classe Math permitem realizar certos clculos matemticos comuns. Por exemplo, o programador que deseja calcular a raiz quadrada de 900.0 poderia escrever:
x = Math.sqrt(900.0);

Quando essa instruo executada, ela chama o mtodo static sqrt da classe Math para calcular a raiz quadrada do nmero 900.0, que , neste caso, o parmetro (ou argumento) do mtodo sqrt. A instruo precedente avaliada como 30.0. O mtodo sqrt recebe um argumento do tipo double e devolve um resultado do tipo double. Todos os mtodos da classe Math so static, portanto eles so invocados precedendo-se o nome do mtodo com o nome da classe Math e um operador ponto (.).Para gerar como sada o valor da chamada do mtodo precedente, poderia escrever:
System.out.println (Math.sqrt(900.0));

Nesta instruo, o valor que sqrt devolve se torna o parmetro para o mtodo println. Alguns mtodos da classe Math:
Mtodo abs(x) ceil(x) cos(x) exp(x) floor(x) log(x) max(x,y) min(x,y) pow(x,y) random() round(x) sin(x) sqrt(x) tan(x) Descrio Valor absoluto de x arredonda x para o menor inteiro no menor que x co-seno de x (x em radianos) mtodo exponencial ex arredonda x para o maior inteiro no maior que x logaritmo natural de x (base e) maior valor entre x e y menor valor entre x e y x elevado potncia y gere um numero aleatrio entre 0.0 e 1.0 devolve o prximo inteiro para x do tipo float seno de x (x em radianos) raiz quadrada de x tangente de x Exemplo abs(23.7) 23.7 abs(-23.7) 23.7 ceil(9.2) 10.0 ceil(-9.8) 9.0 cos(0.0) 1.0 exp(1.0) 2.71828 floor(9.2) 9.0 floor(-9.8) -10.0 log(2.71828) 1.0 max(2.3,12.7) 12.7 min(2.3,12.7) 2.3 pow(9.0,.5) 3.0 random() por ex. 0.8 round(3.4) 3.0 sin(0.0) 0.0 sqrt(9.0) 3.0 tan(0.0) 0.0

A classe Math tambm define duas constantes matemticas Math.PI e Math.E. O mtodo Math.random()gera um nmero aleatrio double entre 0.0 e 1.0, mas no incluindo 1.0, e no precisa de receber dados do exterior, por exemplo:
numero = Math.random();

9.3. Organizao de um programa

Elab. por eng Tatiana Kovalenko

22

2008

Disciplina: PA1

Um programa em Java constitudo por uma classe que engloba um conjunto de mtodos independentes. Trs regras importantes so: Um programa contm: odeclaraes de variveis; oum mtodo principal chamado main() (no caso de um applet substitudo por paint()); oum conjunto de mtodos definidos pelo programador; Os mtodos contm: odeclaraes de variveis; oinstrues elementares(atribuio, seleco, repetio, ...); ochamadas de mtodos (pr-definidos ou criados por programador); Um mtodo recebe dados e produz resultados. Os detalhes internos de um mtodo so irrelevantes fora dele. Destas regras decorrem as noes de rea de domnio de variveis, locais e globais. Estas noes esto ligadas ao local, no programa, em que as variveis so declaradas. 9.4. rea de domnio das variveis Existe uma diferena importante entre as instrues e as declaraes de variveis. As instrues tm que estar sempre dentro de um mtodo, enquanto que a declarao de variveis pode estar dentro ou fora de um mtodo. Para alem disso, importante notar que um mtodo no pode utilizar variveis declaradas noutros mtodos. O exemplo a seguir, na hora de compilao vai devolver o erro Undefined variable: valor detectado no mtodo muda().
public class AreaDominio //COM ERRO!!! { public static void main(String args[]) { int valor = 50; //cria varivel valor e inicializa-a System.out.println("Valor = "+valor+ antes da chamada"); muda(); System.out.println("Valor = "+valor+ depois da chamada"); } public static void muda() { valor = 100; System.out.println("Valor = "+valor+ dentro do metodo muda()"); } }

9.5. Variveis locais Variveis declarados dentro de um mtodo chamam-se locais. Eles podem ser utilizados somente dentro do mtodo onde foram declaradas. Por isso, no ltimo exemplo, a varivel valor local ao mtodo main() e no reconhecida no mtodo muda(). Uma varivel local criada sempre que o mtodo activado e destruda quando ele termina a sua execuo. permitido utilizar os mesmos nomes para diferentes variveis no mesmo programa em diferentes mtodos (mas no a boa prtica). Ainda que tenham o mesmo nome, trata-se de variveis diferentes, localizadas em espaos de memria separados. O exemplo a seguir ilustra este facto:
public class AreaDominio_VarLocais { public static void main(String args[]) Valor = 50 { int valor = 50; System.out.println("Valor = "+valor+" antes da chamada"); muda(); System.out.println("Valor = "+valor+" depois da chamada"); } public static void muda() { int valor;
Valor = 100

valor = 100; System.out.println("Valor = "+valor+" dentro do metodo muda()");

Elab. por eng Tatiana Kovalenko

23

2008

Disciplina: PA1

O output ser:
Valor = 50 antes da chamada Valor = 100 dentro do metodo muda() Valor = 50 depois da chamada

9.6. Variveis globais Variveis declarados no incio da execuo do programa, fora de qualquer mtodo, chamam-se globais. Eles podem ser utilizados em qualquer mtodo e so destrudas quando o programa termina. No boa prtica declarar todas as variveis como globais.
public class AreaDominio_VarGlobais { static int valor; Valor = 50 = 100

public static void main(String args[]) { valor = 50; System.out.println("Valor = "+valor+" antes da chamada"); muda(); System.out.println("Valor = "+valor+" depois da chamada"); } public static void muda() { valor = 100; System.out.println("Valor = "+valor+" dentro do metodo muda()"); } } O output ser:
Valor = 50 antes da chamada Valor = 100 dentro do mtodo muda() Valor = 100 depois da chamada

9.7. Passagem de parmetros Em Java, a passagem de parmetros de tipos predefinidos (int, float, boolean, etc.) feita por valor, que significa que no o parmetro real que passado ao mtodo, mas apenas o seu valor. Este tipo de passagem implica que o valor da varivel fica inaltervel aps a execuo do subprograma, independentemente das alteraes feitas. Exemplo:
public class Exemplo { public static void main(String args[]) { int x = 50; //cria varivel x e inicializa-a muda(x); //chamada do mtodo muda com parm. x System.out.println("O contedo da variavel x= "+x); } public static void muda(int valor) { valor = 20; }

O output ser:
O conteudo da variavel x= 50

A execuo deste programa comea pelo subprograma main(), como habitual. Aps de inicializao da varivel x com o valor 50 invocado o mtodo muda(), tendo como parmetro real a varivel x. Este parmetro corresponde ao parmetro formal valor. Durante a execuo do mtodo muda() a varivel valor, inicialmente tendo o valor 50, passado na hora de chamada, recebe o novo valor 20. Ao terminar e execuo do muda(), o controlo devolvido ao programa chamador, que executa a instruo a seguir, visualizando o valor da varivel x que ficou inalterado. Isso acontece porque o valor da varivel x que passado ao subprograma e no a prpria varivel x. 9.8. Valor de retorno

Elab. por eng Tatiana Kovalenko

24

2008

Disciplina: PA1

Todos os mtodos at agora considerados no devolvem qualquer resultado ao mtodo que faz a sua chamada. Este facto confirmado pela presena da palavra reservada void no cabealho. Quando necessrio que o mtodo devolva um valor que calculou, a palavra void deve ser substituda pelo tipo de resultado que o mtodo deve devolver. Exemplo1: Este programa testa o mtodo chamado cubo() que devolve o cubo dum valor do tipo byte passado como parmetro:
public class TestarCubo 1.{ public static void main(String[] args) 2. { for (byte i = 1; i<6; i++) 3. System.out.println (i + "\t"+ cubo(i)); 4. } 5. public static int cubo (byte n) 6. { return n*n*n; //ou int c = n*n*n; 7. } // return c; 8.} O output ser:
11 28 327 464 5125

O mtodo main contm o ciclo for que invoca 5 vezes o mtodo println(). Por sua vez, o mtodo println invoca o mtodo cubo(), passando o valor do argumento i para o parmetro n. O cabealho (linha 8) indica que o mtodo cubo() devolve um resultado do tipo int e recebe um parmetro n do tipo byte. Exemplo2: Este programa testa o mtodo chamado factor() que implementa o calculo de factorial dos nmeros de 0 a 8. O mtodo declara uma varivel local factor do tipo long.
public class TestarFactorial { public static void main(String[] args) { for (int i = 0; i <= 8; i++) System.out.println ("f("+i+")= "+factor(i)); } public static long factor (int n) { long fact = 1; //fact a variavel local while (n > 1) fact *= n--; return fact; } }

O output:

f(0)= f(1)= f(2)= f(3)=


. . .

1 1 2 6

f(8)= 40320

Num mtodo pode haver mais do que uma instruo return. Por exemplo:
public class Sub_Maior3 { public static void main(String[] args) { System.out.println ("O maior entre 3= "+ maior3(5,2,8)); } public static int maior3 (int v1,int v2,int v3) { if (v1>v2 && v1>v3) return v1; else if (v2>v3) return v2; else return v3;
Elab. por eng Tatiana Kovalenko
25

2008

Disciplina: PA1 } }

Formato geral de uma definio de mtodo:


tipo_de_valor_de_retorno nome_do_mtodo (lista de parmetros) { declaraes e instrues }

O nome_do_mtodo qualquer identificador vlido. O tipo_de_valor_de_retorno o tipo de dados do resultado retornado do mtodo para o chamador. O tipo_de_valor_de_retorno void indica que um mtodo no retorna um valor. Os mtodos podem retornar no mximo um valor. Definir um mtodo dentro de outro mtodo um erro de sintaxe.

10. Formatao de sada (output)


As classes NumberFormat e DecimalFormat so utilizadas para a formatao de sada. Ambas classes fazem parte da biblioteca de Java e so definidas em pacote (package) java.text, que deve ser importado logo no incio do programa. Exemplo1:
import java.text.NumberFormat; import java.text.DecimalFormat; import java.util.Locale; public class Formatacao { public static void main (String args[]) { int quant = validaQuant(); double preco = validaPreco(); calculo(quant,preco); } public static int validaQuant() { int q; do { System.out.println("Intr. a quantidade: "); q=Le.umInt(); if (q<=0) System.out.println("Valor invalido!"); } while (q<=0); return q; } public static double validaPreco() { double p; do { System.out.println("Intr. o preco: "); p=Le.umDouble(); if (p<=0) System.out.println("Preco invalido!"); } while (p<=0); return p; } public static void calculo(int qua, double pr) { final double IVA = 17; double subTotal = qua * pr; double taxa = subTotal * IVA / 100; double total = subTotal + taxa; visualizar(subTotal,taxa,total); //chamada do mtodo } public static void visualizar (double s,double tx, double tot) { final double IVA = 0.17,CAMBIO = 24.5; NumberFormat usd= NumberFormat.getCurrencyInstance(Locale.US); NumberFormat perc = NumberFormat.getPercentInstance(); System.out.println("Subtotal = "+ moeda.format(s)); System.out.println("Taxa= "+moeda.format(tx)+" que = "+perc.format(IVA)); System.out.println("Total em USD = "+ moeda.format(tot)); DecimalFormat mt= new DecimalFormat("###,###,###.00 Mt");
Elab. por eng Tatiana Kovalenko
26

2008

Disciplina: PA1

System.out.println("Total em meticais = "+ mt.format(tot*CAMBIO)); } }


Para os valores de input: Intr. a quantidade: 505 Intr. o preco: 1000.27 O output ser: Subtotal = $505,136.35 Taxa = $85,873.18 que = 17% Total em USD = $591,009.53 Total em meticais = 16,548,266.83 Mt

Exemplo2: Calcular a mdia de numeros inteiros introduzidos pelo utilizador. Parar introduzindo um valor negativo.
import java.text.DecimalFormat; public class MediaNumerosFormatada { public static void main (String args[]) { DecimalFormat fmt = new DecimalFormat("##.00"); System.out.println("A media = "+ fmt.format(calcMedia())); } public static double calcMedia() { float soma = 0; int num = 0, quant = 0; while (num >= 0) { System.out.println("Intr.prox. numero positivo (negat.para terminar):"); num = Le.umInt(); if(num >= 0) { soma += num; quant ++; } } System.out.println("Foram introduzidos "+quant+" positivos"); double media = soma/quant; //no usa a diviso de inteiros! soma float return media; } }

Caso introduzir os valores 3, 3 e 3 o output ser:


Foram introduzidos 3 positivos A media dos numeros introduzidos = 3.00

O resultado arredondado, se for necessrio. Pode usar a formatao do tipo "##.##", mas neste caso o output (se for inteiro) aparecera como 3 (mostrando somente a parte inteira).

11. Arrays de tipos de dados primitivos


Os programas que desenvolvemos at aqui tm usado as variveis de todos os tipos de dados de tamanho limitado. Num dado momento cada varivel s pode conter um nico valor. Mas existem casos quando a quantidade de valores a serem tratados elevada. Para isso podem ser utilizados arrays. 11.1. Array de uma dimenso 11.1.1. Criao Um array um objecto que contm uma lista de elementos do mesmo tipo e ocupa um espao na memria. Este conjunto de elementos referenciado pelo um nico nome do array. Para criar um array em primeiro lugar necessrio declarar a referncia para o array. Por exemplo, para declarar um array de notas de alunos:
int notas[]; ou int [] notas; // declara o array

Esta declarao permite criar uma referncia de nome notas que vai referenciar um array de valores do tipo int. Os parnteses rectos que aparecem entre o tipo e o nome da referncia indicam que se trata de um array. Uma vez obtida a referncia, possvel criar o array. Todos os objectos em Java (inclusive arrays) devem ser alocados dinamicamente com o operador new:
notas = new int [50];
Elab. por eng Tatiana Kovalenko

//aloca o espao para array


27

2008

Disciplina: PA1

Esta instruo cria um novo objecto (tabela) com espao para armazenar 50 nmeros inteiros. Os 50 elementos ficam em posies consecutivas na memria e o endereo ( representado pelo smbolo @) do primeiro elemento fica armazenado na referncia notas.
notas @ @ @+1 @+2 @+3 @+4 ... ... @+48 @+49

O programador no ter que se preocupar com o endereo de memria onde fica cada elemento do array, pois acesso ser feito atravs de ndices. Para criar um array podemos unir as duas instrues:
int notas[]= new int [50];

O nmero entre parnteses rectos define o espao de memria reservado para o array, que no significa que o array tenha que conter sempre esse nmero de elementos, podendo conter qualquer valor inferior, inclusivamente zero. Por exemplo, a declarao do array notas poderia ter sido feita depois de solicitar ao utilizador o nmero de notas a armazenar:
System.out.println("Intr. o nmero de notas a armazenar: "); quant = Le.umInt(); int notas[] = new int [quant];

Desta forma possvel adaptar o array s necessidades de cada utilizao. Podemos alocar memria para vrios arrays do mesmo tipo com uma nica declarao. A declarao seguinte reserva 100 elementos para o array byte b e 27 elementos para o array byte x:
byte b[] = new byte[100], x[] = new byte[27];

Outra forma tambm aceitvel:


byte [] b = new byte[100], x = new byte[27];

Java permite a criao e inicializao de um array usando uma forma abreviada, por exemplo:
int diasMes[] = {31,28,31,30,31,30,31,31,30,31,30,31};

Esta instruo cria um array com espao suficiente para os dados fornecidos, procedendo tambm sua inicializao. A instruo anterior equivalente a:
int diasMes[] = new int [12]; diasMes[0] = 31; diasMes[1] = 28;
. . .

diasMes[11] = 31;

Comprimento do array Todos os array em Java conhecem seu prprio comprimento e mantm essa informao numa varivel denominada length que guarda o nmero de elementos com que o array foi criado. Por exemplo:
int [] notas = new int [50]; System.out.println("Numero maximo de notas "+ notas.length);

produz a escrita seguinte no ecr:


Numero mximo de notas 50

11.1.2. Acesso aos elementos de array O acesso a cada um dos elementos do array feito usando um ndice que define a sua posio no array. O primeiro elemento tem o ndice zero, enquanto que o ltimo elemento tem um ndice igual ao nmero dos elementos do array menos 1. Para o nosso exemplo os ndices vlidos vo de 0 a 49. Se for necessrio colocar o valor 14 no primeiro elemento do array e 12, no segundo, pode fazer:
Elab. por eng Tatiana Kovalenko
28

2008

Disciplina: PA1

notas[0] = 14; notas[1] = 12;

Utilizando este tipo de representao podemos redefinir o diagrama anterior, com estes valores nos dois primeiros elementos:
notas @ [0] 14 [1] 12 [2] [3] [4] ... ... [48] [49]

Cada um dos elementos do array pode ser utilizado da mesma forma que uma varivel do tipo de elementos que o array guarda. Sendo notas um array de valores do tipo int, qualquer elemento pode ser utilizado onde possa ser usada uma varivel do tipo int. Por exemplo:
int soma = notas[0] + notas[1]; System.out.println ("A nota do primeiro aluno : " + notas[0]);

O ndice no tem que ser uma constante, podendo ser qualquer expresso que tenha como resultado um nmero inteiro dentro da gama de ndices admissveis para o array. Exemplo: armazenar 30 numeros decimais num array e visualizar o contedo deste array.
public class ArrayLerVisualizar { public static void main (String args[]) { final byte MAX = 30; float valores[]; valores = new float [MAX]; System.out.println ("intr. "+MAX+" valores decimais: "); for (int k=0; k < MAX; k++) { System.out.println ((k + 1)+"-o valor: "); valores[k] = Le.umFloat(); System.out.println("Estes sao valores armazenados no array:"); for (int z = 0; z < valores.length; z++) System.out.print(valores[z] + " ");

Para criar uma cpia de um array j existente, necessrio criar um segundo array do mesmo tipo e com as mesmas dimenses e, depois, fazer a atribuio explcita de todos os seus elementos:
int [] notas1=new int [50], notas2=new int [50]; for (int i = 0; i < notas1.length; i++) notas2[i] = notas1[i];

Um erro frequente usar as seguintes instrues para a mesma tarefa:


int [] notas1=new int [50], notas2=new int [50]; notas2 = notas1;

Lembrando que notas1 e notas2 so referncias, pelo que armazenam endereos e no valores do array, a instruo notas2 = notas1; coloca o endereo que estava em notas1 na notas2, pelo que ambas as referncias ficam com o endereo do array notas1. Assim continua existir o mesmo array em memria.
notas1 @ [0] 14 notas2 @@ X X [0] [1] [2]
29

[1] 12

[2]

[3]

[4]

... ...

[48]

[49]

[3]

[4]

...

[48]

[49]
2008

Elab. por eng Tatiana Kovalenko

Disciplina: PA1

10

...

Exemplo: Inicializar os elementos de um array de 10 elementos com os inteiros pares de 2 a 20 e visualizar o contedo de array na forma de duas colunas: indice e o respectivo valor.
public class ArrayNumerosPares { public static void main (String args[]) { final int MAX = 10; int lista[] = new int [MAX]; for (int a = 0; a < lista.length; a++) //ou lista[a] = 2 * (a + 1); // System.out.println ("Indice\tValor\n"); for (int k = 0; k < lista.length; k++) System.out.println (k + "\t" + lista[k]); for (int a = 1;a <= MAX;a++) lista[a-1] = 2 * a;

} }

Boa prtica: utilizar mtodos separados para realizao de diferentes tarefas. Exemplo: Ler as notas de teste de um conjunto de N alunos e armazenar num array, calcular a nota mdia do grupo.
public class ArrayMediaNotas { public static void main (String args[]) { int quant = validarQuant(); System.out.println("A media das "+ quant + " notas introduzidas= "+ Math.round(calcMedia(quant))); } public static int validarQuant () { int x; do { System.out.println("Intr. o numero de notas: "); x = Le.umInt(); if (x <= 0) System.out.println("Introduza a quantidade > 0!"); } while (x <= 0); return x; } public static double calcSoma (int q) { int notas[] = new int [q]; double soma = 0; System.out.println("Introduza notas de "+q+" alunos:"); for (int i=0; i<notas.length; i++) { System.out.println ("\t"+"nota do "+(i+1)+"-o aluno: "); notas[i] = Le.umInt(); soma = soma + notas[i]; } return soma;

public static double calcMedia (int k) { double m = calcSoma(k) / k; return m; }

12. Array passado como parmetro


Array pode tambm ser passado como parmetro para um mtodo. Esta possibilidade tem bastante utilidade. Para passar um array como parmetro para um mtodo, se especifique o nome do array (sem parnteses rectas []).
public class ArrayPassParamLerVisualizar { public static void main (String args[]) { byte quant = leQuantValida(); int valores[]=new int [quant]; //ou int valores[] = lerArmazenar(quant); valores = lerArmazenar(quant); System.out.println("Os valores armazenados no array:");
Elab. por eng Tatiana Kovalenko
30

2008

Disciplina: PA1

visualValores (valores);

//passagem de array como parmetro

} public static byte leQuantValida() { byte x; do { System.out.println("Quantos valores vai armazenar? "); x = Le.umByte(); if (x <= 0) System.out.println("Quantidade incorrecta!"); } while (x <= 0); return x; } public static int[] lerArmazenar (byte q) { int val[] = new int [q]; System.out.println ("intr. "+ q +" valores inteiros: "); for (byte m = 0; m < q; m++) { System.out.println((m+1)+"-o valor: "); val[m] = Le.umInt(); } return val;
}

public static void visualValores(int v[]) { for (byte k=0; k < v.length; k++) System.out.print(v[k]+", ");
} }

Um outro exemplo um mtodo capaz de calcular e devolver a mdia dos elementos de um array:
//Mtodo que calcula a mdia dos elementos de um array de int,recebe // o array(a referncia) e o numero de elementos que tem. Devolve a media public static float calculaMedia(int tab[], byte numElements) { float soma = 0; //tem que ser float para evitar a diviso de inteiros for (byte z = 0; z < numElements; z++) soma += tab[z]; return soma / numElements; }

Para alem do array, este mtodo recebe ainda como parmetro o nmero de elementos que este contm. A existncia deste parmetro torna este mtodo mais genrico, pois pode ser usado independentemente do array estar preenchido ou no (nada obriga, a que um array tenha todos os elementos preenchidos). A chamada deste mtodo no programa poderia ser assegurada pela instruo:
media = calculaMedia (notas, numNotas);

Em Java os parmetros so passados por valor, o que implica que os parmetros reais no so modificados, independentemente das alteraes feitas aos parmetros formais dentro dos mtodos. O mesmo acontece neste caso, pelo que notas e numNotas ficam inalterados aps a execuo do mtodo. No entanto, dentro do mtodo, o parmetro formal tab, corresponde a notas e, por isso, contendo tambm o endereo do 1o elemento do array, pode ser utilizado para introduzir alteraes nos elementos do array. Alterar um elemento de um array dentro de um mtodo modifica o contedo do array original, pelo que as alteraes feitas ao array dentro de um mtodo se reflectem fora dele. Notar que possvel passar como parmetro real um qualquer elemento de um array. Exemplo: Considera-se que foram criadas dois arrays, cada um com 5 nmeros inteiros:
int lista1[] = {11,22,33,44,55}; int lista2[] = {99,99,99,99,99};

Veremos alguns blocos de instrues que incluem um mtodo e a sua chamada: Bloco 1:
Elab. por eng Tatiana Kovalenko
31

2008

Disciplina: PA1

//recebe a referncia para um array public static void imprimeLista(int tab[], int numElements) { for (int i = 0; i< numElements; i++) System.out.print(tab[i]+ ", "); System.out.println(); } System.out.println ("No inicio..."); imprimeLista(lista1,5); imprimeLista(lista2,5);

O output ser:
No inicio... 11, 22, 33, 44, 55, 99, 99, 99, 99, 99,

Bloco 2:
//recebe um inteiro public static void passaElemento(int num) { num = 1234; } passaElemento (lista1[1]); System.out.println ("Lista apos passaElemento..."); imprimeLista(lista1,5);

O output ser:
Lista apos passaElemento... 11, 22, 33, 44, 55,

Neste bloco o mtodo recebe um parmetro do tipo int, que neste caso tomou o valor de lista1[1], ou seja 22. Como sabido, os parmetros so passados por valor, pelo que a alterao do parmetro formal efectuada dentro do mtodo no se reflecte c fora e o array fica inalterado. Bloco 3:
//recebe uma referncia para um array de inteiros public static void mudaElementos(int tab[]) { tab[2] = 77; tab[4] = 88; } mudaElementos (lista1); System.out.println ("Lista apos mudaElemento..."); imprimeLista (lista1,5);

O mtodo mudaElementos() recebe a referncia para um array de inteiros como parmetro. A instruo que chama esse mtodo fornece lista1 como parmetro real. Desta forma, sendo os parmetros passados por valor, a referncia lista1 no ser alterada. No entanto, o parmetro formal tab ter durante a execuo do mtodo o mesmo valor que lista1, pelo que sua utilizao leva a alteraes no array. O output ser:
Lista apos mudaElemento... 11, 22, 77, 44, 88,

Bloco 4:
//recebe as referncias para duas listas de inteiros public static void passaReferencia(int tab1[], int tab2[]) { tab1 = tab2; } passaReferencia (lista1, lista2); System.out.println ("lista1 e lista2 apos passaReferencia..."); imprimeLista (lista1,5); imprimeLista (lista2,5);

Dentro de mtodo as referncias recebidas so igualadas, mas essas modificaes no se reflictam fora do mtodo, pelo que nada se altera. O output ser:
lista1 e lista2 apos passaReferencia... 11, 22, 77, 44, 88,
Elab. por eng Tatiana Kovalenko
32

2008

Disciplina: PA1

99, 99, 99, 99, 99,

Bloco 5:
//recebe as referncias para duas listas de inteiros public static void copiaLista(int tab1[], int tab2[]) { for (int index = 0; index< tab1.length; index++) tab1[index] = tab2[index]; } copiaLista (lista1, lista2); System.out.println ("lista1 e lista2 apos copiaLista..."); imprimeLista (lista1,5); imprimeLista (lista2,5);

O output ser:
lista1 e lista2 apos copiaReferencia... 99, 99, 99, 99, 99 99, 99, 99, 99, 99

Bloco 6:
//recebe a referncia para uma lista, devolve a referncia para uma lista public static int[] devolveReferencia (int tab[]) { tab[1] = 11; return tab; } lista1 = devolveReferencia (lista2); System.out.println ("lista1 e lista2 apos devolveReferencia..."); imprimeLista (lista1,5); imprimeLista (lista2,5);

O mtodo recebe a referncia para um array, altera um dos seus elementos e devolve a referncia do array. Tendo em conta a chamada efectuada, constata-se que lista2 passada como parmetro real, pelo que o seu elemento com ndice [1] ser alterado. No entanto, a referncia para este array devolvida e atribuda referncia lista1 (devido a instruo de atribuio). Deste modo, lista1 e lista2 sero referncias para o mesmo array (lista2), tendo o objecto anteriormente referenciado por lista1 ficado inacessvel (o espao de memria por ele ocupado ser devolvido automaticamente ao sistema operativo). O output ser:
lista1 e lista2 apos devolveReferencia... 99, 11, 99, 99, 99, 99, 11, 99, 99, 99,

Destes exemplos, possvel concluir que apesar da passagem de parmeros ser feita por valor, quando passada uma referncia para um array, as alteraes feitas ao array dentro do mtodo so visveis fora dele.

13. Algoritmos de procura e ordenao


13.1. Algoritmo de procura de valor maior / menor num array Para encontrar o valor maior num array de inteiros poderia usar o mtodo seguinte:
public static int procValorMaior(int y[]) { int maiorNum = y[0]; //inicializao da varivel com 1 elemento do array for (int i=0; i<y.length; i++) if (y[i] > maiorNum) // para procura do valor menor usa a condiao (<) maiorNum = y[i]; return maiorNum; }

13.2 Ordenao por borbulhamento Um problema fundamental em computao a ordenao de dados. Existem vrios mtodos de ordenao: por borbulhamento (bubble sort), por seleco (selection sort), tipo Shell (shell sort), shaker sort, quick sort, etc. A tcnica usa dois ciclos for encadeados para fazer vrias passagens pelo array. O ciclo externo controla o nmero de passagens pelo array. O ciclo interno controla as comparaes e trocas (se so necessrias) dos elementos durante cada passagem. Em cada passagem, pares de elementos sucessivos so comparados: se um par estiver na ordem crescente (ou os valores

Elab. por eng Tatiana Kovalenko

33

2008

Disciplina: PA1

forem iguais), a bubble sort deixa os valores como esto, se um par estiver na ordem decrescente, a bubble sort troca seus valores no array. O algoritmo muito simples, mas lento.
public class ArrayOrdenacaoBubbleSort { public static void main (String args[]) { int lista[] = {9,6,14,8,10,12,89,68,45,37}; System.out.println("Conteudo do array original:\n"); visualValores (lista, lista.length); bubbleSort(lista); // chamada do metodo para ordenao System.out.println("Conteudo do array ordenado:\n"); visualValores (lista, lista.length); } public static void visualValores(int x[], int m) { for (int k=0; k < m; k++) System.out.print(x[k] + ", "); System.out.println(); } public static void bubbleSort(int y[]) { for (int i = 1; i < y.length; i++ ) for (int j = 0; j < y.length - 1; j++ ) if (y[j] > y[j + 1]) troca (y, j, j + 1); } public static void troca(int ar[],int primeiro,int segundo) { int aux; aux = ar[primeiro]; ar[primeiro] = ar[segundo]; ar[segundo] = aux; }

13.2. Ordenao por seleco simples (Selection sort) Algoritmo por seleco consiste em percorrer os elementos e em cada passagem colocar um elemento na sua posio correcta. Para isso determina-se a posio de 1 menor elemento e troca-se com elemento que est na 1a posio. Na segunda passagem determina-se a posio de 2 menor dos restantes elementos e coloca-se na sua posio correcta, e assim sucessivamente.

10

20

15

50

12

10

20

15

50

12

20

15

50

10

12

10

15

50

20

12

10

12

50

20

15

10

12

15

20

50

Elab. por eng Tatiana Kovalenko

34

2008

Disciplina: PA1

O programa de ordenao com passagem de parmetros:


public class ArrayOrdenacaoPorSeleccao { public static void main (String args[]) { int valores[] = {5,10,20,15,50,4,12}; System.out.println ("Conteudo do array antes de ordenar: "); visualLista(valores); ordenacao(valores); System.out.println ("Depois de ordenacao: "); visualLista(valores); } public static int indiceMin(int w[], int inicio, int fim) { int i_menor = inicio; for (int k = inicio+1; k <= fim; k++) if (w[i_menor] > w[k]) i_menor = k; return i_menor; } public static void trocaElementos(int m[], int a, int b) { int aux = m[a]; m[a] = m[b]; m[b] = aux; } } public static void ordenacao (int x[]) { for (int i = 0; i < x.length-1;i++) trocaElementos(x,i,indiceMin(x, i, x.length-1)); } public static void visualLista (int y[]) { for (int z = 0; z < y.length; z++) System.out.print (y[z]+" "); System.out.println(); }

14. Noes bsicas de classes e objectos


Boa parte de nosso entendimento e relacionamento com o mundo se d atravs do conceito de objectos. Ao observarmos as coisas e seres que existem ao nosso redor, existe uma natural tendncia a tentarmos identificar o que cada uma destas diferentes entidades. Ao olharmos para uma bola de futebol reconhecemos sua forma esfrica, seu tamanho usual, colorido tpico e aplicao. Mas a bola que observamos no a nica que existe, inmeras outras esto por a e mesmo possuindo caractersticas idnticas so objectos distintos. Como o prprio nome diz, a bola de futebol, ou seja, para ser usada no esporte que denominamos futebol, um tipo de bola especfica. Assim bola de futebol a mais do que identidade de um certo objecto que estamos observando mas um tipo de objecto que apresenta caractersticas prprias (pense na descrio genrica de qualquer bola de futebol). Existem outras bolas (outros tipos) que no so de futebol. Bolas especiais para os mltiplos esportes diferentes e bolas de recreao so exemplos de outros objectos que compartilham das mesmas caractersticas de uma bola, ou melhor, de uma esfera. Pense agora num outro objecto, uma batedeira. Como utilizamos este electrodomstico? Atravs dos controles existentes e da colocao de alimentos lquidos e slidos em seu copo. A batedeira pode estar desligada ou ligada em diferentes velocidades. Isto significa que podemos oper-la atravs de operaes de desligar, ligar, carregar (colocar algo no seu copo), aumentar ou diminuir sua velocidade. Mesmo sem saber como funciona internamente este aparelho somos capazes de us-lo correctamente. Detalhes de sua estrutura ficam ocultos dentro de sua carcaa pois temos acesso apenas aos controles que o projectista julgou necessrio para seu uso domstico. Atravs destes dois exemplos cotidianos descrevemos caractersticas da programao orientada aos objectos: Identidade Classificao Polimorfismo Hereditariedade
Elab. por eng Tatiana Kovalenko
35

informalmente

as

principais

2008

Disciplina: PA1

Encapsulamento. Para nos relacionarmos com os objectos do mundo ns os denominamos de alguma forma, ou seja, todos os objectos tem um nome que os representa. Ao mesmo tempo que cada objecto tem uma identidade e caractersticas prprias, somos capazes de reconhecer categorias de objectos, ou seja, grupos de objectos que compartilham caractersticas comuns embora distintas em cada objecto (os serem humanos tem caractersticas comuns: estrutura e funcionamento do corpo, embora possam ser distinguidos por sua altura, idade, peso, cor e aparncia da pele, olhos, cabelos, pelos etc.). natural, para o nosso entendimento de mundo, criarmos uma classificao para as coisas, ou seja, criarmos classes de objectos para facilitar nossa compreenso do mundo. Polimorfismo se refere a nossa capacidade de nos reconhecer num objecto particular um outro mais geral, por exemplo: podemos falar de uma bola de futebol em termos de uma bola genrica, podemos tratar uma batedeira como um electrodomstico genrico, podemos tratar morcegos, cachorros e golfinhos como animais mamferos. A hereditariedade um mecanismo de criarmos novos objectos a partir de outros que j existem, tomando como prontas e disponveis as caractersticas do objecto origem. Isto cria a possibilidade de criarmos vrias classes, hierarquicamente relacionadas, partindo de uma mais geral para diversas outras mais especializadas, tal como a classificao proposta pela biologia para classificao dos seres vivos. Finalmente o encapsulamento indica que podemos utilizar um objecto conhecendo apenas sua interface, isto , sua aparncia exterior, tal como fazemos muitas vezes com computadores, automveis e outras mquinas de nosso tempo. A programao orientada objectos (POO) uma forma de programao que se baseia na construo de classes e na criao de objectos destas classes, fazendo que estes trabalhem em conjunto para que os propsitos da criao de um programa sejam atingidos. Esta nova forma de programar, embora mais complexa, muito mais apropriada para o desenvolvimento de sistemas pois permite tratar os problemas de forma semelhante ao nosso entendimento de mundo ao invs de dirigir a soluo para as caractersticas de funcionamento dos computadores tal como faz o paradigma da programao procedural. Um objecto uma combinao de dados ou atributos (variveis) e aces (mtodos) logicamente relacionados. Um objecto pode ser caracterizado por trs componentes: identidade; atributos; comportamento. A identidade permite identificar o objecto, os atributos permitem caracterizar o objecto e o comportamento define o conjunto de funcionalidades que pode executar por opo prpria ou a pedido de outro objecto. comum ter num programa objectos semelhantes, com mesmo comportamento, mas com atributos e identidade diferentes. Em qualquer linguagem OO primeiro deve se definir a classe e depois objectos (um ou mais) que pertencem a esta classe, cada um deles com atributos prprios, mas com os mesmos comportamentos. O b je c to J o a o
tr u to s Uma classe um tipo de objecto que podeAseri bdefinido pelo programador para descrever uma J o a o entidade real ou abstracta. Podemos entender cuma o classe como um modelo ou como uma m a u lin s lt ir o especificao para certos objectos, ou seja,o a e descrio genrica dos objectos individuais 3 0 pertencentes a um dado conjunto. A bola Cde mfutebola m e n t o s uma classe que descreve os o p o r t pode ser r a b a lh a d r C bola de Tfutebol. Ao definio de uma classe a d o s la s s e i n s e r i r d envolve a definio de variveis as quais objectos v is u a liz a r d a d o s A tr ib to s m u a r e s a d o c a se associamuefunes que controlam o acesso a destes. t Assim i v i lcriao de uma classe implica n o m s e x o em definir um tipo de objecto em termos de seus atributos (variveis que contero os dados) e e s t a d o c iv il seus mtodos (funes que manipulam tais dados). id a d e C o m p o uma e n t o s a m A relao entre rdt a d o classe e um objecto dessa classe: in s e r ir s v is u a liz a r d a d o s m u d a r e s t a d o c iv il O b je c to M a n u e l A tr ib u to s M a n u e l m a s c u lin o v iu v o 6 0 O b je c to O lg a A tr ib u to s O lg a f e m e n in o c a s a d a 4 0 C o m p o rta m e n to s in s e r ir d a d o s v is u a liz a r d a d o s m u d a r e s t a d o c iv il

Elab. por eng Tatiana Kovalenko

36 C o m p o rta m e n to s in s e r ir d a d o s v is u a liz a r d a d o s m u d a r e s t a d o c iv il

2008

Disciplina: PA1

Transportando este exemplo para a POO, poderia existir uma classe Trabalhador que define que os objectos desta classe tm os atributos nome, sexo, estado civil e idade e apresentam os comportamentos inserir dados, visualizar dados e mudar estado civil. Posteriormente, possvel criar objectos a partir do molde definido pela classe (os objectos Joao, Manuel e Olga, por exemplo). Cada um deles deve ter valores para os atributos (um nome, um sexo, um estado civil e uma idade) e capaz de apresentar os comportamentos definidos. O nmero de objectos criados a partir de uma classe no limitado. Em resumo, pode-se dizer que os objectos so entidades criadas a partir de classes que definem os seus atributos (variveis que guardam as caractersticas do objecto) e os comportamentos que podem apresentar (mtodos). Note que um mesmo objecto pode ser descrito de diferentes maneiras, sendo cada uma destas maneiras mais ou menos adequada para representar tal objecto dentro de um determinado contexto, ou seja, dentro um de um certo problema. Um objecto pode ordenar a outro objecto que efectue uma determinada tarefa se esta estiver definida entre os seus comportamentos. Em terminologia da POO esta ordem chamada mensagem (na realidade corresponde chamada de um mtodo definido no outro objecto). Costumam os nomes das classes comear por uma maiscula e os nomes dos objectos por uma minscula. 14.1. Criao de uma classe A criao de uma classe passa pela definio dos atributos e dos comportamentos que os objectos criados a partir dessa classe devem apresentar. Exemplo: introduzir dados sobre N trabalhadores e determinar a idade mdia deles. Em primeiro lugar definimos uma classe Trabalhador com os atributos que o trabalhador pode possuir. O cdigo completo desta classe apresentado em seguida:
public class Trabalhador { //Atributos private short codigo; private byte idade; //-------------------------------------------------------------------------//Construtor. Recebe valores iniciais dos atributos (nome e idade) public Trabalhador() { System.out.println("Codigo (1111-9999): "); codigo = validarCod(); System.out.println("Idade (18-65): "); idade = validarIdade(); } //-------------------------------------------------------------------------//Valida o codigo fornecido do teclado. private short validarCod() { short cod; do { cod=Le.umShort();
Elab. por eng Tatiana Kovalenko
37

2008

Disciplina: PA1

} //-------------------------------------------------------------------------//Valida a idade fornecida do teclado. private byte validarIdade() { byte id; do { id=Le.umByte(); if( id<18 || id>65) System.out.println("Nao pode trabalhar com essa idade!Tente de novo"); } while (id<18 || id>65); return id; } //-------------------------------------------------------------------------//Devolve a idade. public byte getIdade() { return idade; } //-------------------------------------------------------------------------//Devolve uma linha (um String) de informao sobre o trabalhador. public String toString() { return "Codigo\tIdade\n"+codigo+"\t"+idade; } }

if(cod<1111 || cod>9999) System.out.println("Codigo invalido!Tente de novo"); } while (cod<1111 || cod>9999); return cod;

14.1.1. Atributos Na declarao de atributos utiliza-se a palavra reservada private (que serve para alterar as permisses de acesso a qualquer membro de uma classe, veja pag.258 do A.Mendes) em vez de public. Desta forma, indica-se ao compilador que estas variveis s podem ser acedidas directamente pelos mtodos (comportamentos) definidos na prpria classe.
private short codigo; private byte idade;

Assim, os atributos de um objecto criado a partir da classe Trabalhador mantm-se inacessveis a partir de qualquer outro objecto, ainda que criado a partir da mesma classe. Esta opo permite criar cada objecto como uma entidade fechada ou encapsulada, cujos detalhes internos ficam escondidos dentro dos prprios objectos. ( possvel dirigir um carro sem conhecer a estrutura de motor, por exemplo). 14.1.2. Construtores Cada classe deve ter pelo menos um construtor. Trata-se de um tipo especial de mtodo utilizado apenas na criao e inicializao de objectos da classe. Distinguem-se dos restantes mtodos por terem o mesmo nome da classe e por no terem valor de retorno, nem mesmo void . Os construtores no so chamados como os outros mtodos. Apenas a instruo de criao de objectos da classe os pode chamar. Estes mtodos so usados muitas vezes para inicializar os atributos de um objecto. Se nenhum construtor definido para uma classe, o compilador cria um construtor default que no recebe nenhum argumento. Boa prtica fornecer um construtor para assegurar que cada objecto seja inicializado com valores significativos. Os atributos podem ser inicializadas implicitamente com seus valores default (0 para tipos numricos primitivos, false para tipo booleano e null para referncias), podem ser inicializadas em um construtor da classe ou seus valores podem ser configurados mais tarde, depois que objecto for criado. No caso da classe Trabalhador, as variveis so inicializadas dentro do mtodo construtor:
public Trabalhador() { System.out.println("Codigo (1111-9999): "); codigo = validarCod(); System.out.println("Idade (18-65): "); idade = validarIdade();
Elab. por eng Tatiana Kovalenko
38

2008

Disciplina: PA1

14.1.3. Comportamentos (Mtodos) Para alem de construtor, podem ser considerados diversos comportamentos (mtodos) para um trabalhador. Considerem-se, por exemplo, os seguintes:
validarCod() validarIdade() getIdade() toString() valida o cdigo, introduzido do teclado valida a idade, introduzida do teclado devolve o valor da idade visualiza os dados de um trabalhador

Como se pode observar, a declarao dos atributos e a definio dos mtodos feita no interior da classe que comea com o cabealho:
public class Trabalhador Trabalhador o nome da classe que vai posteriormente permitir a criao de objectos desta classe. O cdigo acima, uma vez guardado num ficheiro de nome Trabalhador.java, define um

novo tipo de dados composto por dois atributos e um conjunto de comportamentos. Esta estrutura pode ser representada pelo diagrama:
public class Trabalhador { . . . private short codigo; private byte idade; public Trabalhador() { . . .; } private short validarCod() { . . .; } private byte validarIdade() { . . .; } public byte getIdade() { . . .; } public String toString() { . . .; } } codigo idade

Como mostra a figura, as variveis cdigo e idade foram declaradas fora dos mtodos, pelo que esto acessveis em qualquer deles, para consulta ou modificao. Nota: 1). A palavra static no utilizada na definio da classe. 2). No existe um mtodo main() na definio da classe. De facto, a definio de uma classe no idntica criao de um programa, pois trata-se apenas da definio de um tipo de dados que vai ser utilizado para criar objectos. claro que a classe s ser til se integrada num programa (ou um applet) que ter um mtodo main() (ou um mtodo paint()). 14.2. Criao de objectos. Instanciao A criao de um objecto o que chamamos instanciao. Instanciar significa criar uma instncia da classe, isto , um novo objecto que pode ser descrito atravs desta classe. Enquanto uma classe um modelo abstracto de um objecto, uma instncia representa um objecto concreto desta classe. Do ponto de vista computacional, a instanciao corresponde a alocao de memria para armazenar informaes sobre um certo objecto. Depois de construir uma nova classe, j possvel escrever um programa que utiliza objectos criados a partir dessa classe. Para isso, o programador deve declarar os objectos e, posteriormente, reservar o espao de memria necessrio para os armazenar. A declarao de um objecto pode ser feita com uma declarao semelhante das variveis de tipos simples:
ClasseDoObjecto nomeDoObjecto;

Concretizando para o caso do trabalhador:


Elab. por eng Tatiana Kovalenko
39

2008

Disciplina: PA1

Trabalhador trab;

Esta declarao no cria o objecto, mas apenas cria na memria um espao capaz de armazenar um endereo do espao de memria onde um objecto deste tipo venha a ser armazenado (chamamos por referncia, por permitir referenciar um objecto da classe Trabalhador), mas o seu valor, neste momento indefinido. Podemos representar de seguinte maneira:
trab

A criao de objectos feita atravs do operador new. Este operador deve ser seguido do nome da classe a partir da qual se pretende criar o objecto e de parnteses, contendo (ou no) um conjunto de parmetros. Sintaxe:
NomeDoObjecto = new ClasseDoObjecto(parmetros);

O operador new verifica qual o espao de memria necessrio para armazenar o objecto (em funo das caractersticas da classe) e reserva-o. O endereo respectivo devolvido e armazenado na referncia custa do operador de atribuio. Deste modo o acesso posterior ao objecto ser possvel atravs da referncia. O operador new encarrega-se de chamar o construtor da classe, permitindo a realizao das operaes de inicializao nele definidos. Concretizando para o caso do trabalhador, a instruo seguinte permite criar um novo objecto da classe Trabalhador, guardar o seu endereo na referncia trab e inicializar os seus atributos:
Trabalhador trab = new Trabalhador();
trab 0x4055324

0x4055324
codigo 1265 Trabalhador() validarCod() validarIdade() getIdade() toString() idade 35

O operador new reservou um espao de memria suficiente para armazenar todos os atributos (variveis) do objecto, bem como para guardar uma cpia em bytecode de todos os mtodos definidos na classe Trabalhador. O endereo de memria a partir do qual o objecto foi armazenado (0x4055324 neste exemplo) guardado na referncia trab, permitindo o acesso posterior ao objecto sua custa. A localizao de um objecto em memria no controlada pelo programador, ficando o espao respectivo ocupado at que o objecto seja destrudo. Tendo em conta que uma referncia no tem utilidade antes de ser colocada a apontar (referenciar) para um objecto, comum juntar as instrues de criao da referncia e do objecto numa s:
Trabalhador trab = new Trabalhador();

O objecto assim definido um representante da classe, caracterizado pelo seu conjunto de dados. Em terminologia de POO, diz-se que o objecto uma instncia da classe, pelo que as suas variveis (atributos) so variveis de instncia. A classe Trabalhador define atributos codigo e idade para seus objectos. Para indicarmos qual destes atributos desejamos utilizar utilizamos um outro operador denominado selector indicado por um ponto como segue: nomeDoObjeto.nomeDoAtributo

Elab. por eng Tatiana Kovalenko

40

2008

Disciplina: PA1

Esta construo pode ser lida como: seleccione o atributo nomeDoAtributo do objecto nomeDoObjeto. Com o nome da varivel objecto seleccionamos o objecto em si e atravs do selector indicamos qual atributo deste objecto que desejamos utilizar. Usar um atributo pode significar uma de duas operaes: consultar seu contedo (get), ou seja, ler ou obter seu valor e determinar seu contedo(set), isto , escrever ou armazenar um certo valor neste atributo. A primeira situao envolve o atributo numa expresso qualquer enquanto na segunda situao temos o atributo recebendo o resultado de uma expresso qualquer atravs de uma operao de atribuio. Agora escrevemos o programa que vai utilizar a classe Trabalhador.
public class TrabalhadorTest { public static void main(String args[] ) { System.out.println("Quantos trabalhadores sao? "); int num = validQuant(); System.out.println ("idade media dos "+num+" trabalhadores="+ calcMedia(num)); } private static int validQuant() { int q; do { q = Le.umInt(); if( q <= 0) System.out.println("A quant. deve ser > 0"); } while (q <= 0); return q; } public static float calcMedia (int n) { float soma = 0; for (int i = 1; i<= n; i++) { System.out.println("Dados do "+i+"-o trabalhador:"); Trabalhador trab = new Trabalhador(); System.out.println("===========================" ); System.out.println(trab); //chamada do metodo toString() System.out.println("===========================" ); soma += trab.getIdade(); } return Math.round(soma/n); } }

O output ser:
Dados do 1-o trabalhador: Codigo (1111-9999): Idade (18-65): =========================== Codigo Idade 1212 19 =========================== Dados do 2-o trabalhador: Codigo (1111-9999): Idade (18-65): =========================== Codigo Idade 1215 52 =========================== A idade media dos 2 trabalhadores=36.0

15. Classe String


A classe String uma das classes predefinidas da Java e serve para manipular cadeias de caracteres. 15.1. Criao de um objecto da classe String Para criar um objecto da classe String pode usar uma instruo que declara a referncia e cria objecto:
String frase = new String ("Programar aprende-se programando");

Elab. por eng Tatiana Kovalenko

41

2008

Disciplina: PA1

Dado que a utilizao de objectos da classe String muito frequente, a linguagem Java permite a sua criao usando uma forma abreviada:
String frase = "Programar aprende-se programando";

Esta instruo tem um resultado igual anterior, ou seja, cria uma referncia para um objecto da classe String (frase) e cria o objecto guardando nele a cadeia de caracteres fornecida. O endereo do objecto guardado em frase. Uma das dificuldades associadas com manipulao deste tipo de informao a de que as cadeias de caracteres podem ter tamanhos muito diferentes. Para limitar a complexidade associada a este facto, a linguagem Java define o tamanho do objecto em funo da cadeia de caracteres com que criado, no permitindo alteraes posteriores. Assim, em Java os objectos da classe String so imutveis, ou seja, uma vez que lhes seja atribudo um valor, este no pode ser alterado. 15.2. Mtodos da classe String A classe String inclui um conjunto de mtodos que permitem efectuar diversas operaes sobre objectos deste tipo. Aconselha-se a consulta documentao da classe para uma referncia completa dos mtodos existentes. Um dos mtodos permite determinar o tamanho da cadeia de caracteres: Mtodo length():
//determina o nmero de caracteres da cadeia //Recebe: Nada. Devolve: Nmero de caracteres (int) public int length()

Exemplo:
String frase = "Programar aprende-se programando"; System.out.print("Numero de caracteres: "+frase.length());

Resultado da execuo:
Numero de caracteres: 32

Existem vrios mtodos destinados a localizar caracteres ou cadeias de caracteres noutra cadeia: Mtodo charAt():
//devolve um caracter da cadeia de caracteres //Recebe: ndice do caracter que se quer receber //Devolve: caracter localizado na posio indice (char) public char charAt(int indice)

Exemplo:
String frase = "Programar aprende-se programando"; System.out.print("Caracter na posicao 0: " + frase.charAt(0));

Resultado da execuo:
Caracter na posicao 0: P //Os caracteres esto nas posicoes 0-31

Mtodo indexOf():
//determina a localizao da 1a ocorrncia de uma cadeia de caracteres //dentro da cadeia de caracteres do objecto //Recebe: cadeia de caracteres a procurar //Devolve: indice do 1o caracter da cadeia de caracteres //ou 1 se a cadeia de caracteres no existir(int) public int indexOf (String str)

Exemplo:
String frase = "Programar aprende-se programando"; System.out.print("Posicao de aprende: "+frase.indexOf("aprende")); System.out.print("Posicao de aprender: "+frase.indexOf("aprender"));

Resultado da execuo:
Posicao de aprende: 10 Posicao de aprender: -1

Mtodo equals():

//testa se a cadeia de caracteres do objecto igual a uma fornecida //Recebe: cadeia de caracteres a comparar
42

Elab. por eng Tatiana Kovalenko

2008

Disciplina: PA1

//Devolve: true se forem iguais, false se foram diferentes public boolean equals (String outraString)

Exemplo:
String frase = "Programar aprende-se programando"; String segundaFrase = "Por isso, preciso programar muito"; if (frase.equals(segundaFrase)) System.out.print("So iguais"); else System.out.print("So diferentes");

Resultado da execuo:
So diferentes

No pode comparar duas cadeias de caracteres utilizando a instruo: if (frase == segundaFrase) ... que na realidade compara as suas referncias, que sempre contm os endereos de memria diferentes. Mtodo equalsIgnoreCase():
//testa se a cadeia de caracteres do objecto igual a uma fornecida //sem destingir letras maisculas de minsculas //Recebe: cadeia de caracteres a comparar //Devolve: true se forem iguais, false se foram diferentes public boolean equalsIgnoreCase (String outraString)

Exemplo:
String frase = "Programar aprende-se programando"; String segundaFrase = "PROGRAMAR APRENDE-SE PROGRAMANDO"; if (frase.equalsIgnoreCase (segundaFrase)) System.out.print("So iguais"); else System.out.print("So diferentes");

Resultado da execuo:
So iguais

Mtodo compareTo():
//compara a cadeia de caracteres do objecto com uma fornecida //Recebe: cadeia de caracteres a comparar. Devolve: 0 se forem iguais, //um valor negativo se a cadeia do objecto for alfabeticamente anterior // do parmetro, ou um valor positivo se for posterior (int) public int compareTo (String outraString)

Exemplo:
String frase = "Programar aprende-se programando"; String segundaFrase = "Por isso, preciso programar muito"; if (frase.compareTo(segundaFrase) == 0) System.out.print("So iguais"); else if (resultado < 0) System.out.print("A cadeia do objecto anterior"); else System.out.print("A cadeia do objecto posterior");

Resultado da execuo:
A cadeia do objecto posterior

A classe String integra tambm mtodos que permitem efectuar transformaes sobre as cadeias de caracteres. Mtodo concat():
//Junta a cadeia de caracteres do objecto com outra fornecida //Recebe: cadeia de caracteres a concatenar //Devolve: nova cadeia de caracteres (String) public boolean concat (String str) String frase = "Programar aprende-se programando."; String segundaFrase = "Por isso, preciso programar muito."; frase = frase.concat(segundaFrase);
Elab. por eng Tatiana Kovalenko
43

Exemplo:

2008

Disciplina: PA1

System.out.print (frase);

Resultado da execuo:
Programar aprende-se programando. Por isso, preciso programar muito.

O mtodo concat(), tal como outros que sero apresentados em seguida, devolve um novo objecto da classe String, deixando o objecto original intacto. Como a referncia para este novo objecto foi armazenada em frase, o endereo do objecto inicial, que estava nesta referncia, perde-se. Daqui resulta a destruio desse objecto, a menos que exista uma outra referncia para ele. Caso se pretenda manter o objecto inicial, deve ser usada uma nova referncia. Por exemplo:
String novaFrase = frase.concat(segundaFrase);

O operador + pode ser utilizado como alternativa ao mtodo concat(), quando pelo menos um dos operandos um objecto da classe String.
frase = frase.concat(segundaFrase); //ou frase = frase + segundaFrase;

Se for necessrio, este operador transforma um tipo simples em caracteres para poder efectuar a concatenao. Por exemplo:
String frase = "Hoje dia " int dia = 12; frase = frase + dia; System.out.println (frase);

resulta em
Hoje dia 12

Mtodo toLowerCase():
//Cria uma cadeia de caracteres igual do objecto com maisculas //transformadas em minsculas //Recebe: Nada. Devolve: nova cadeia de caracteres (String) public String toLowerCase()

Exemplo:
String frase = "Programar aprende-se programando."; novaFrase = frase.toLowerCase();

Resultado da execuo:
Programar aprende-se programando.

Mtodo toUpperCase() semelhante ao anterior, transformando a cadeia de caracteres para maisculas. Mtodo subString():
//Devolve uma cadeia de caracteres contida na cadeia de caracteres //do objecto //Recebe: ndice do 1o caracter a incluir (beginIndex) e ndice //do 1o caracter que j no deve ser incluido (endIndex) //Devolve: nova cadeia de caracteres (String) public String subString (int beginIndex, int endIndex) String frase = "Programar aprende-se programando."; novaFrase = frase.subString(10,17);

Exemplo: Resultado da execuo:


Aprende

15.3. A classe StringTokenizer


Muitas vezes necessrio dividir uma cadeia de caracteres nas palavras que a compem. Isso possvel utilizando apenas mtodos da classe String. No entanto, a classe StringTokenaizer, definida na biblioteca java.util, inclui um conjunto de mtodos que permitem obter o mesmo resultado de uma forma mais simples. Exemplo:
import java.util.StringTokenizer;

public class StringTokenier { public static void main(String args[]) { String frase = "Programar aprende-se programando"; StringTokenizer divisor = new StringTokenizer(frase);
Elab. por eng Tatiana Kovalenko
44

2008

Disciplina: PA1

} }

while (divisor.hasMoreElements()) { String palavra = divisor.nextToken(); System.out.println(palavra); }

O programa comea por criar e inicializar um objecto da classe String. Este objecto referenciado por frase e contm a cadeia de caracteres a dividir. Em seguida, a instruo com new cria um objecto da classe StringTokenizer, referenciado por divisor. Repare-se que a cadeia de caracteres foi fornecida como parmetro ao construtor da classe StringTokenizer, pelo que divisor inicializado com essa cadeia. A separao das palavras que constituem a cadeia de caracteres conseguida custa de dois mtodos da classe StringTokenizer. O mtodo hasMoreElements() permite determinar se a diviso j foi completada. Quando tal acontecer, este mtodo devolver false, levando ao fim o ciclo while. Por sua vez, o mtodo nextToken() devolve a prxima palavra da cadeia de caracteres. Para o fazer, considera que as palavras esto separadas por um ou mais espaos em branco. Desta forma, o resultado da execuo do programa :
Programar aprende-se programando

A classe StringTokenizer tem outro construtor que pode ser utilizado quando se pretende utilizar um separador diferente. Por exemplo, no caso de desejar considerar a vrgula, o ponto e virgula e o espao como separadores, poderia fazer:
StringTokenizer divisor = new StringTokenizer(frase, ",; ");

16. Array de objectos


Nos exemplos anteriores array armazenava dados de tipos primitivos. Array de objectos um array (ou tabela) cujos elementos so objectos ou, mais correctamente, referncias para objectos. 16.1. Array de objectos do tipo String Um exemplo a criao de um array de cadeias de caracteres:
String frases[] = new String [4];

Esta instruo cria um array com espao para 4 referncias para objectos da classe String. No entanto, no cria as cadeias de caracteres propriamente ditas, mas apenas as suas referncias. As cadeias de caracteres tm que ser criadas explicitamente. Por exemplo:
frases[0] frases[1] frases[2] frases[3] = = = = new new new new String("Querer poder"); String("Compreender para aprender"); String("Penso logo existo"); String("Devagar se vai ao longe");

A situao resultante da criao e inicializao de um array de elementos da classe String representada na figura seguinte:
frases @ [0] @1 [1] @2 [2] @3 [3] @4

@1
Querer poder Mtodos...

@2
Compreender para aprender Mtodos...

@3
Penso logo existo Mtodos...

@4
Devagar se vai longe Mtodos...

Como se pode verificar, os elementos do array frases so referncias para objectos da classe String situados noutras localizaes da memria. Este exemplo mostra que possvel criar estruturas de dados bastante complexas apenas utilizando array de objectos. Por outro lado, da
Elab. por eng Tatiana Kovalenko
45

2008

Disciplina: PA1

mesma forma que um array pode conter referncias para objectos, um objecto pode ter atributos que so arrays. 16.2 Criao de um array de objectos Temos sempre lembrar a caracterstica importante de array de objectos: criao de array e criao de objectos, que sero armazenados no array, so duas coisas separadas. Instanciao de um array de objectos reserva o espao para armazenamento somente das referencias. Objectos que devem ser armazenados num array devem ser instanciados separadamente. Exemplo: desenvolver um programa que leia os dados de um conjunto de estudantes (nome, e um conjunto de notas), calcule a sua mdia e ordene os estudantes por ordem decrescente das mdias. O 1o passo ser definir uma nova classe, a classe Estudante, para representar um estudante, que ter como atributos o nome, as notas e a mdia e como comportamentos a utilizao, o clculo da mdia, o acesso mdia e a escrita dos seus dados:
public class Estudante { //Atributos private String nome; private int notas[]; private float media; //Construtor da classe, promove a inicializao dos atributos public Estudante() { System.out.println ("Nome: "); nome = Le.umaString(); System.out.println ("Quantas notas? "); int numNotas = validarQuant(); notas = introdNotas(numNotas); media = calcMedia(); } private int validarQuant() { int t; do { t = Le.umInt(); if( t<0) System.out.println("Introduziu um valor negativo!"); } while (t<0); return t; } //Cria array Notas e preenche com notas do aluno private int[] introdNotas(int numN) { notas = new int[numN]; for (int i = 0; i < numN; i++) { System.out.println ((i+1)+"-a nota: "); notas[i] = Le.umInt(); } return notas; } //devolve um String composto pelos notas de um estudante private String visualNotas() { String visual=""; for (int k = 0; k < notas.length; k++) visual += notas[k]+" "; return visual; } //Mtodo para clculo da mdia de um estudante private float calcMedia() { float soma = 0; for (int z=0; z<notas.length; z++) soma += notas[z]; return soma / notas.length; } public float getMedia() { return media; }
Elab. por eng Tatiana Kovalenko
46

2008

Disciplina: PA1

public String toString() { return "As notas de "+nome+" sao: "+visualNotas()+" Meida="+media; }

Apos a definio da classe Estudante, possvel criar uma classe que represente uma turma de estudantes. Esta classe vai guardar um conjunto de objectos da classe Estudante. Como comportamentos apresenta a inicializao, a escrita dos dados de todos os estudantes e a ordenao dos estudantes por ordem decrescente da sua mdia. O nico atributo desta classe ser uma varivel para armazenar os dados de todos os estudantes, ou seja, um array de objectos da classe Estudante:
private Estudante lista[];

O construtor da classe ter que obter o nmero de estudantes, criar o array correspondente e, finalmente, ler os dados de cada estudante. Esta ltima operao conseguida custa da criao de objectos da classe Estudante. O seu construtor encarrega-se da inicializao de cada um destes objectos (leitura dos dados do estudante e clculo da sua mdia). O endereo de memria onde cada objecto foi criado devolvido e armazenado no array lista, pois este na realidade um array de referncias para objectos da classe Estudante. O construtor:
public Turma() { System.out.print("Numero de estudantes"); int numEst = Le.umInt(); lista = new Estudante[numEst]; //Cria array de objectos for (int i = 0; i < numEst; i++) lista[i] = new Estudante(); }

O mtodo que prepara a escrita dos elementos duma turma:


public String toString() { String visualizar=""; for (int k=0;k<lista.length;k++) visualizar += lista[k] + "\n"; return visualizar; }

//parte lista[k].toString() opcional

Para ordenar a turma utilizamos o algoritmo de ordenao por seleco. A principal diferena entre ordenao de array de dados de tipo primitivo e array de objectos consiste em possibilidade de comparar valores entre si. Como decidir se um objecto maior(ou menor) do que outro. Na realidade comparam-se valores que encontram-se nas variveis do tipo primitivo.
public void ordenaTurma() { Estudante aux; int i_maior; for (int i = 0; i < lista.length-1; i++) { i_maior = localizaMaior(i); aux = lista[i]; lista[i] = lista[i_maior]; lista[i_maior] = aux; } }

Uma vez que os elementos de lista so referncias para objectos, as trocas efectuadas s alteram o posicionamento de cada referncia dentro do array. Os objectos continuam nas mesmas localizaes de memria, apenas a ordem pela qual sero acedidos que foi modificada. Este mtodo utiliza um metido auxiliar, que localiza o elemento com maior mdia existente entre o elemento de ndice i, que fornecido como parmetro, e o fim do array. Devolve o ndice em que se encontra esse elemento:
//Localiza o elemento com a maior media numa parte do array //Recebe o ndice do 1o elemento a considerar (inicio) private int localizaMaior(int inicio) { int i_maior = inicio; //considera que o maior o indice do 1o elem. //percorre a tabela desde o indice inicio ate ao final for (int k = inicio+1; k < lista.length ; k++) if (lista[k].getMedia() > lista[i_maior].getMedia())
Elab. por eng Tatiana Kovalenko
47

2008

Disciplina: PA1

i_maior = k; return i_maior;

O mtodo comea por considerar que o maior elemento o que est colocado no incio da rea de pesquisa e que fornecido como parmetro. Graas ao ciclo for, este valor ser comparado com os restantes. Sempre que for encontrado um elemento com mdia superior considerada como maior nesse momento, a varivel i_maior passa a assinalar esse objecto. A mdia desse objecto passar a ser comparada com a dos elementos subsequentes. Quando o ciclo termina, a varivel i_maior contm o ndice do elemento com maior mdia, pelo que devolvida. Este mtodo foi declarado como private, pois apenas um mtodo auxiliar que no deve ser chamado a partir de outro objecto. O programa completo da classe Turma:
public class Turma { private Estudante lista[]; //Construtor public Turma() { System.out.println("Numero de estudantes"); int numEst = validarQuant(); //Cria o array com o numero de elementos necessrio lista = new Estudante[numEst]; for (int i = 0; i < numEst; i++) { System.out.println("Dados do "+ (i+1)+"-o estudante:"); lista[i] = new Estudante(); //dento de ciclo cria os objectos que so estudantes } private int validarQuant() { int t; do { t = Le.umInt(); if( t<0) System.out.println("Introduziu um valor negativo!"); } while (t<0); return t; } public void ordenaTurma() { Estudante aux; int i_maior; for (int i=0; i < lista.length-1;i++) { i_maior = localizaMaior(i); aux = lista[i]; lista[i] = lista[i_maior]; lista[i_maior] = aux; } } //Localiza o elemento com maior media numa parte de array //Recebe o ndice do 1o elemento a considerar (inicio) private int localizaMaior(int inicio) { int i_maior = inicio; for (int k = inicio+1; k < lista.length ; k++) if (lista[k].getMedia() > lista[i_maior].getMedia()) i_maior = k; return i_maior; } public String toString() { String visualizar=""; for (int k=0;k<lista.length;k++) visualizar += lista[k] + "\n"; //equivale a lista[k].toString() return visualizar; } }

Para que as classes Estudante e Turma possam ser utilizadas, necessrio criar um programa que as use. Esta a funo da classe GereTurma:
public class GereTurma
Elab. por eng Tatiana Kovalenko
48

2008

Disciplina: PA1

{ public static void main(String args[]) { Turma t = new Turma(); //cria um objecto da classe Turma System.out.println("Lista de estudantes: "); System.out.println(t); //equivale a System.out.println(t.toString()); t.ordenaTurma(); System.out.println("\nLista ordenada por media: "); System.out.println(t); } }

Esta classe muito simples, limitando-se a ter um mtodo main(). A sua 1a instruo a criao de um objecto da classe Turma. O construtor desta classe cria o array de estudantes e os objectos deste array. O construtor da classe Estudante procede leitura dos dados que lhe correspondem. Posteriormente, escrita a lista de estudantes pela ordem em que foram inseridos pelo utilizador, ordenado o array de estudantes e, finalmente, escrita novamente a lista de estudantes, agora ordenada por ordem decrescente da mdia.

17. Ficheiro do tipo texto


Os objectos e as variveis dos tipos at agora utilizados partilham a caracterstica de serem armazenados na memria central do computador. Isto significa que s existem durante a execuo do programa, pelo que os dados s esto acessveis durante esse perodo do tempo. A resoluo desse problema guardar os dados em ficheiros, que so conjuntos organizados de dados armazenados em dispositivos de memria permanente. Para conseguir arquivar e ler dados de ficheiros, a linguagem Java utiliza o conceito de fluxo (stream em ingls). 17.1. Fluxos de dados J aprendemos algumas operaes de entrada e sada de dados. A entrada de dados (leitura) permite transmitir informao do teclado para a memria central, enquanto que a sada de dados (escrita) possibilita a transmisso de informao da memria central para o ecr do computador. Estes fluxos de dados, teclado memria e memria ecr, permitem ao programa comunicar com o utilizador:
fluxo leitura
Programa

Teclado fluxo
Ecr

escrita
Programa

Substituindo o teclado por um ficheiro, obtm-se o conceito de fluxo de leitura de um ficheiro, e substituindo o ecr por um ficheiro, obtm-se o conceito de fluxo de escrita num ficheiro:
fluxo
Ficheiro

leitura
Programa

fluxo
Ficheiro

escrita
Programa

Desta forma, um fluxo de leitura permite a leitura de dados a partir de um ficheiro existente e a sua transmisso para a memria central, onde so armazenados e, eventualmente, processados. Um fluxo de escrita num ficheiro permite a transmisso de dados do programa para o ficheiro, onde so armazenados. Para Java cada ficheiro considerado como um fluxo sequencial de bytes. Cada ficheiro acaba com um marcador de fim de ficheiro. Um programa Java abre um ficheiro atravs de criao de um objecto e associao de um fluxo de bytes a este objecto.
0 1 2 3 4 5 ... ... n-1 Marcador de fim de ficheiro

Java inclui vrias classes que permitem definir estes fluxos de dados, cada uma das quais adequada a um determinado tipo de dados e forma de representao. Estas classes foram includas na biblioteca java.io, pelo que esta deve ser importada para qualquer programa que
Elab. por eng Tatiana Kovalenko
49

2008

Disciplina: PA1

as use. A hierarquia de classes oferecida pelo pacote java.io bastante grande e relativamente complexa pois oferece 58 classes distintas para o processamento de entrada e sada em ficheiros de acesso sequencial, aleatrios e compactados. Os ficheiros de texto s podem conter caracteres. Para guardar valores de outros tipos em ficheiros de texto, necessrio converter estes valores para cadeias de caracteres. 17.2. Manipulao de ficheiros de texto. Classe File A classe File serve para representar ficheiros em disco. Para criar um objecto desta classe pode usar:
File f1 = new File(nomeDoFicheiro);

onde nomeDoFicheiro um objecto da classe String que indica o nome (caminho) do ficheiro a ler ou escrever. O objectivo principal da classe File criar uma representao lgica do ficheiro e evitar que o programador tenha que se preocupar com as formas como os diversos SO lidam com ficheiros. Esta classe pode tambm ser usada para representar directrios, bastando que o parmetro seja o nome de um directrio, em vez de um ficheiro. A criao de um objecto da classe File no garante por si s a criao de um ficheiro, ou directrio em disco. No entanto, se o ficheiro j existir, este objecto fornece alguns mtodos que podem ser teis. No caso dos directrios, esta classe pode mesmo ser utilizada para a sua criao, o que pode ser til para organizar os ficheiros manipulados por um programa. Alguns mtodos da classe File: delete() exists() length() renameTo(File) setReadOnly() listFiles() mkdir() apaga o ficheiro ou directrio; devolve true se o ficheiro ou directrio existir e false caso contrrio; devolve o tamanho do ficheiro (no funciona com directrios); altera o nome do ficheiro ou directrio para o nome do objecto que recebe como parmetro; marca o ficheiro ou directrio como s de leitura; devolve uma tabela de objectos da classe File, cada um representando um dos ficheiros do directrio; cria um subdirectrio no directrio corrente;

Uma das operaes que pode ser assegurada por objectos da classe File a verificao da existncia de um ficheiro:
File f1 = new File("c:/Trabalhos/UmFich.txt"); if (f1.exists()) System.out.print("Ficheiro existe"); else System.out.print("Ficheiro no existe");

Para alterar o nome de um ficheiro j existente:


File f1 = new File("UmFich.txt"); File f2 = new File("NovoFich.txt"); f1.renameTo(f2);

A classe File, contudo no possui mtodos que implementam as operaes mais comuns sobre os ficheiros, como sejam criar o ficheiro, ler ou escrever para o ficheiro. Para o fazer, necessrio utilizar outras classes mais especializadas, dependendo do tipo de ficheiro e da operao em causa. No caso dos ficheiros de texto, podem ser utilizadas as classes FileReader e FileWriter, consoante a operao desejada. Para criar objectos destas classes, necessrio fornecer como parmetro um objecto da classe File correspondente ao ficheiro pretendido:
FileReader frd = new FileReader (new File(nomeDoFicheiro)); FileWriter fwt = new FileWriter (new File(nomeDoFicheiro));

ou de forma abreviada:
FileReader frd = new FileReader (nomeDoFicheiro); FileWriter fwt = new FileWriter (nomeDoFicheiro);

Elab. por eng Tatiana Kovalenko

50

2008

Disciplina: PA1

Estas classes so especficas de ficheiros de caracteres, permitindo a sua leitura ou escrita caracter a caracter. Como resultado das instrues acima, as referncias frd e fwt ficam com o endereo do incio do ficheiro. Para conseguir a leitura e escrita mais rpida, linha a linha, e armazenado tais dados num buffer, reduzindo o nmero de operaes fsicas, utilizam-se as classes: BufferedReader (para leitura) e BufferedWriter (para escrita), que recebem um objecto da classe FileReader e FileWriter, respectivamente, como parmetro:
BufferedReader fR = new BufferedReader (frd); BufferedWriter fW = new BufferedWriter (fwt);

Estas classes possuem convenientes para a leitura e escrita de linhas de caracteres, tornandose, por isso, mais convenientes para a manipulao de ficheiros. No caso da abertura de um ficheiro em modo de escrita, pode verificar-se uma de duas situaes: o ficheiro no exista e os seus contedos so apagados. Em qualquer dos casos, o processo de abertura de um ficheiro para escrita resulta num ficheiro vazio. Para fechar ficheiros utiliza-se o mtodo close() da classe BufferedReader e BufferedWriter: A leitura de uma linha a partir de um ficheiro de texto pode ser feita utilizando o mtodo readLine() da classe BufferedReader: Exemplo 1: Ler de um ficheiro do tipo texto N linhas de nomes e visualiz-los no ecr.
import java.io.*; public class LerFicheiroNomesNlinhas { public static void main (String args[])throws IOException { String umaLinha="", nomeFich = "Nnomes.txt"; FileReader fr = new FileReader(nomeFich); BufferedReader fichIn = new BufferedReader(fr); while (umaLinha != null) { umaLinha = fichIn.readLine(); System.out.println (umaLinha); } fichIn.close(); // ate atingir fim de ficheiro //l uma linha do ficheiro

} }

As palavras throws IOException so obrigatrias para todos os mtodos que incluam operaes de entrada /sada ou que chamem mtodos que as incluam. A sua funo indicar ao compilador que o mtodo pode gerar ou propagar um erro do tipo IOException, que se verifica por exemplo, quando se tenta abrir para leitura um ficheiro inexistente. Mais tarde ser apresentada a forma como estes erros podem ser detectados nos prprios mtodos, evitando assim a sua propagao. comum utilizar ficheiros de texto para armazenar representaes de nmeros, um em cada linha. Claro que internamente, os nmeros so armazenados como cadeias de caracteres, pelo que aps a leitura de uma linha necessrio converter a cadeia de caracteres obtida para um nmero. O exemplo seguinte refere-se a nmeros do tipo int. utilizado o mtodo parseInt() da classe Integer para efectuar a converso. A classe Integer uma representao, sob a forma de objecto, de um int. Quando se l um ficheiro, muitas vezes, o nmero de linhas no conhecido, pelo que a leitura feita at chegar ao fim do ficheiro. Quando se l para alem da ltima linha, o resultado devolvido pelo mtodo readLine() null. Nesta situao, h que evitar chamar o mtodo Integer.parseInt(), pois resultaria num erro de execuo (null no uma representao de um nmero inteiro). O objectivo facilmente atingido atravs de uma instruo de seleco que evita que se chame Integer.parseInt() quando o valor da varivel umaLinha null. Repare-se que no Exerccio 1 este problema no se coloca, porque ao devolver um objecto da classe String, quando devolve null indica que o valor lido no vlido. Exemplo 2 Ler de um ficheiro do tipo texto N linhas de nmeros (um nmero em cada linha), converter, calcular a sua soma e visualizar no ecr.
import java.io.*;
Elab. por eng Tatiana Kovalenko
51

2008

Disciplina: PA1

public class LerFicheiroNNumeros { public static void main (String args[])throws IOException { String umaLinha="", nomeFich = "nnumeros.txt"; int numero; long soma=0; FileReader fr = new FileReader(nomeFich); BufferedReader fichIn = new BufferedReader(fr); while (umaLinha != null) // ate atingir fim de ficheiro { umaLinha = fichIn.readLine(); if (umaLinha != null) //q-do se le apos de ultima linha dev. null(nao int) { numero = Integer.parseInt(umaLinha); //converte String num inteiro System.out.println(numero); soma += numero; } else System.out.println ("Fim do ficheiro!"); } fichIn.close(); System.out.println("Soma de todos os numeros ="+soma); } }

A escrita de uma cadeia de caracteres para um ficheiro de texto pode ser obtida com o mtodo write() da classe BufferedWriter. O mtodo newLine() inclui no ficheiro os caracteres que indicam mudana de linha, fazendo com que a prxima escrita se faa no incio da linha seguinte. Exemplo 3 Criar um ficheiro de texto com 5 nomes lidos do teclado.
import java.io.*; public class EscreverNomesNoFich { public static void main (String args[]) throws IOException { final int MAX = 5; String umaLinha, nomeFich = "nomes.txt"; FileWriter fw = new FileWriter(nomeFich); BufferedWriter fichOut = new BufferedWriter(fw); for (int i = 1; i<= MAX; i++) { System.out.println ("Introduza "+i+" nome: "); umaLinha = Le.umaString(); fichOut.write(umaLinha+" "); //escreve nome lido para o ficheiro } fichOut.close(); System.out.println ("O ficheiro de saida foi criado com nome "+nomeFich); } }

Exemplo 4 Criar um ficheiro de texto com 15 linhas, em cada linha escrever um s numero (comeando pelo 1). Ler do ficheiro os numeros, achar o produto deles e visualizar no ecr
import java.io.*; public class EscrLerFichNNumeros { public static void main (String args[])throws IOException { String nomeFich = "criarnum.txt"; escreverNum(nomeFich); lerNum(nomeFich); } public static void escreverNum (String nome) throws IOException { final int MAX = 15; String str = ""; FileWriter fw = new FileWriter(nome); BufferedWriter fichOut = new BufferedWriter(fw); for (int i = 1; i <= MAX; i++) { fichOut.write(str.valueOf(i)); fichOut.newLine(); }
Elab. por eng Tatiana Kovalenko

//write(i) tambm funciona

52

2008

Disciplina: PA1

fichOut.close(); System.out.println ("O ficheiro foi criado com nome "+nome);

public static void lerNum (String nomeF) throws IOException { int numero; byte cont = 0; long prod=1; String umaLinha = ""; FileReader fr = new FileReader(nomeF); BufferedReader fichIn = new BufferedReader(fr); while (umaLinha != null) // ate atingir fim de ficheiro { umaLinha = fichIn.readLine(); if (umaLinha != null) { numero = Integer.parseInt(umaLinha); //converte String em int System.out.println (numero); prod *= numero; cont++; } else System.out.println (" Fim do ficheiro!"); } fichIn.close(); System.out.println ("Produto de "+cont+" numeros="+prod);

} }

Na fase de leitura do ficheiro no se usou o conhecimento de que o ficheiro contm quinze linhas. Geralmente, quando se manipulam ficheiros, a dimenso destes no conhecida, pelo que o ciclo de leitura ter que determinar quando o ficheiro termina. Neste caso, utilizou-se o primeiro elemento do array devolvido por lerNumeroInt(), para verificar se o fim do ficheiro foi atingido (valor diferente de zero) ou no (valor igual a zero). 17.4. Excepes Ao executar um programa frequente que ocorram situaes inesperadas. Por exemplo: um utilizador que escreve uma letra quando se espera um inteiro; um ficheiro que o programa necessita abrir foi apagado, alterado o seu nome ou a sua localizao; outros. necessrio preparar os programas para estes casos, ou seja, para as excepes. Uma excepo uma indicao de que ocorreu um problema durante a execuo de um mtodo e que o impede de funcionar de acordo com o que estava previsto. O tratamento de excepes projectado para processar condies excepcionais problemas que no acontecem frequentemente, mas podem acontecer. Por serem muito propcios ocorrncia de excepes, os mtodos que utilizam operaes de entrada e sada devem obrigatoriamente tratar as excepes ou declarar a sua propagao custa da clusula throws. No entanto, a propagao de excepes s deve ser permitida se o mtodo em causa no as conseguir tratar, por exemplo, por no possuir toda a informao necessria. Em resumo, quando ocorre uma excepo, o programa pode reagir das seguintes formas: ignor-la, o programa termina com uma mensagem de sistema (no recomendado); trat-la no mtodo onde ocorre (se houver a informao suficiente); trat-lo noutro mtodo da cadeia de chamada do mtodo onde se verificou a excepo (a excepo propagada at chegar a esse mtodo). A instruo trycatch permite detectar e tratar excepes. O mtodo tenta, em primeiro lugar, executar as instrues includas no bloco try. Se no for gerado qualquer erro a execuo prossegue para instruo seguinte ao bloco catch. No caso de ocorrer um erro (excepo), os blocos catch so verificados, procurando-se um que se aplique ao tipo de excepo que surgiu. No caso de usar trycatch no necessrio indicar as palavras reservadas throws IOException. Uma vez que a excepo tratada no interior do mtodo, j no necessrio propag-la.
Elab. por eng Tatiana Kovalenko
53

2008

Disciplina: PA1

Um bloco try pode ser acompanhado por vrios blocos catch, quando a(s) instruo(es) includa(s) no try pode(m) gerar mais do que um tipo de excepo e se pretender dar um tratamento diferenciado a cada uma dessas excepes. Sintaxe:
try { //instrues que podem levar ao aparecimento de uma . . . . } catch (Excepcao1 ex1) { // instrues a executar se ocorrer uma excepo de . . . . } catch (Excepcao2 ex2) { // instrues a executar se ocorrer uma excepo de . . . . } catch (Excepcao3 ex3) { // instrues a executar se ocorrer uma excepo de . . . . } excepo tipo Excepcao1 tipo Excepcao2 tipo Excepcao3

Exemplo: Ler do ficheiro do tipo texto N linhas de dados (cdigo, nome de artigo e preo), visualizar no ecr e calcular o preo mdio de produtos.
import java.util.StringTokenizer; import java.io.*; public class LerFichConvertVisual { public static void main (String args[])//throws IOException { StringTokenizer umaCadeia; //uma porcao de informacao a ser dividia por Str.Tokenizer String umaLinha="", nomeArtigo, nomeFich = "Dados.txt"; int cod, cont=0; float s = 0, prec; try { FileReader fr = new FileReader(nomeFich); BufferedReader fichIn = new BufferedReader(fr); umaLinha = fichIn.readLine(); while (umaLinha != null) // ate atingir fim de ficheiro { umaCadeia = new StringTokenizer (umaLinha); cod = Integer.parseInt(umaCadeia.nextToken()); //extrai o cdigo nomeArtigo = umaCadeia.nextToken(); //extrai nome de artigo prec = Float.parseFloat(umaCadeia.nextToken()); //extrai o preo s = s + prec; //acumula a soma dos preos System.out.println (cod+"\t"+nomeArtigo+"\t"+prec); umaLinha = fichIn.readLine(); cont++; } System.out.println("Preo mdio de "+cont+" produtos = "+ s/cont); fichIn.close(); } catch (FileNotFoundException exception) { System.out.println("Ficheiro "+ nomeFich + "nao encontrado!"); } catch (IOException exception) { System.out.println(exception); } } }

18. Array bidimensional


Um array unidimensional pode armazenar elementos de tipos simples e tambm elementos que so objectos. Um caso particular quando cada elemento de array um array, criando-se assim um array bidimensional, ou matriz, com linhas e colunas. O modelo simplificado duma matriz:
precos @ [0]
Elab. por eng Tatiana Kovalenko
54

[1]
2008

Disciplina: PA1

[0] [1] [2] float precos[][]; precos = new float [3][2];

precos[0][0] precos[1][0] precos[2][0]

precos[0][1] precos[1][1] precos[2][1]

Declarao dum array bidimensional com 3 linhas e 2 colunas pode ser feita de maneiras: ou
float precos[][] = new float [3][2];

ou
float [][] precos={{120.54,100.34}, {100.12, 98.34}, {157.89,180.12}};

Cada elemento do array bidimensional pode ser acedido atravs de dois ndices, um que indica a linha e outro a coluna. Por exemplo, o elemento precos[2][1], de acordo com a ultima declarao, possui o valor 180.12. possvel obter: o nmero de linhas dum array atravs de instruo:
int numLinhas = precos.length;

o nmero de colunas dum array atravs de


int numColunas = precos[0].length;

Para aceder aos elementos do array deve se utilizar dois ciclos for, um dentro do outro. O primeiro serve para fazer variar linhas e o segundo para fazer variar colunas. O exemplo a seguir preenche um array de 3 linhas e 2 colunas com valores aleatrios, geridos pelo mtodo nextFloat() da classe Random, e depois visualiza o contedo do array no ecr na forma de tabela:
import java.util.Random; public class Array2ParamClassRandom { public static void main (String args []) { int tabela[][] = criarArray(); visualArray(tabela); } public static int[][] criarArray() { int t[][] = new int [3][2]; Random r = new Random(); for (int i=0; i < t.length; i++) for (int j=0; j<t[0].length; j++) t[i][j]= Math.round(100*(r.nextFloat())); return t; } public static void visualArray(int x[][]) { for (int i=0; i<x.length; i++) //visualiza na forma de tabela { for (int j=0; j<x[0].length; j++) System.out.print(x[i][j]+" "); System.out.println(); } }

Um outro exemplo a procura do valor maior num array bidimensional, cujos elementos so introduzidos do teclado:
public class Array2Maior { public static void main (String args []) { int tabela[][] = criarArray(); visualArray(tabela); System.out.print("Maior valor = "+acharMaior(tabela)); } public static int[][] criarArray () { int x[][] = new int [3][2]; for (int i = 0; i < x.length; i++) for (int j = 0; j < x[0].length; j++)
Elab. por eng Tatiana Kovalenko
55

2008

Disciplina: PA1

{ System.out.println("Intr. o x[i][j] = Le.umInt(); } return x;

"+i+","+j+" valor=");

public static void visualArray(int x[][]) { for (int i=0; i<x.length; i++) //visualiza na forma de tabela { for (int j=0; j<x[0].length; j++) System.out.print(x[i][j]+" "); System.out.println(); } } public static int acharMaior(int y[][]) { int maiorNum = y[0][0]; for (int i=0; i < y.length; i++) for (int j=0; j < y[0].length; j++) if (y[i][j] > maiorNum) maiorNum = y[i][j]; return maiorNum; }

Elab. por eng Tatiana Kovalenko

56

2008