Introdução à Linguagem Java Fernando Silva DCC-FCUP Estruturas de Dados Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 1 / 87 A Linguagem Java Linguagem de programação divulgada pela Sun Microsystems em 1995: I I I início do desenvolvimento: 1991 líder da equipa: James Gosling da Sun Microsystems a partir de 2009, pertence à Oracle Sintaxe muito próxima do C: I mas não tem apontadores! Orientada a objectos (OO): I I I os programas são classes noção de objecto é fundamental propriedades OO: abstracção, encapsulamento, herança e polimorfismo. outras linguagens OO que lhe antecederam: I I I smalltalk (1980) - a primeira linguagem de referência C++ (1985) - acrescentou a orientação aos objectos ao C outras: Simula (1967), Eiffel, C#, Ruby, Scala, Python, Groovy Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 2 / 87 Vantagens do Java linguagem OO relativamente pura portabilidade: I I compila para byte-code (código intermédio) basta ter uma máquina abstracta (java virtual machine/JVM) para executar o programa. segurança e robustez: I I I ao carregar o byte-code, a máquina abstracta verifica a sua validade gestão de memória intrinseca (com garbage-collection) detecta erros em tempo de execução gerando excepções que podem ser “apanhadas” pelo programa reutilização de código – deriva do facto de ser OO Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 3 / 87 Processo de Programação Envolve um conjunto de etapas: definir as especificações do problema a resolver conceber um algoritmo que resolva o problema codificar o algoritmo numa linguagem de programação de alto-nível documentar o algoritmo/programa de forma a torná-lo compreensível para terceiros testar o programa num conjunto de dados de input significativo de forma a eliminar erros fazer a manutenção do programa ao longo do tempo. Neste processo, o desenvolvimento pode beneficiar de bons princípios de programação como a modularidade (ou abstracção procedimental) que consiste em dividir programas em módulos mais simples e de menor complexidade. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 4 / 87 Modularidade e abstracção Modularidade: agrupar procedimentos e funções em módulos; ajuda a diminuir complexidade do programa; identificar funcionalidades permitindo reutilização em outros programas; identificar mais rapidamente partes do programa que têm de ser modificadas sem mexer no programa todo; O programador precisa apenas de conhecer a interface do módulo (nome de procedimento e tipo de argumentos) para poder usá-lo, ficando assim escondidos detalhes de implementação do módulo. A esta capacidade designamos por: Abstracção: capacidade de abstrair dos detalhes (complexidade) deixando apenas o que é fundamental para uso do conceito. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 5 / 87 Encapsulamento Encapsulamento consiste em “esconder” os detalhes associados à implementação de um módulo, deixando apenas visível uma interface bem definida através da qual pode haver interacção com o exterior. Uma programação baseada em abstracção de dados (esconder detalhes de implementação dos dados) designa-se por programação orientada a objectos. No paradigma de programação OO, existem três entidades fundamentais: I I I objecto – repositório de informação (dados) classe – caracterização geral do tipo de objecto método – procedimento ou função que opera sobre um objecto Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 6 / 87 Classes e Objectos Classe: é a base de encapsulamento e representa uma abstracção de um conjunto de objectos que partilham a mesma estrutura e comportamento; Uma classe descreve os atributos gerais de um objecto através da definição de um template que inclui os tipos dos atributos (variáveis ou dados) e funções (métodos) que operam sobre eles. Objecto: é uma instância particular de uma classe, pelo que é também constituído por um conjunto de dados e métodos que operam sobre esses dados. É comum objectos de diferentes classes estarem relacionados e por vezes constituirem hierarquias de objectos. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 7 / 87 Herança e Polimorfismo Herança: é a capacidade de as classes poderem “herdar” atributos e métodos de classes mais gerais. I I Uma classe ListaCompras herda de uma classe Lista a propriedade de armazenar uma lista de ítens. Uma classe Funcionario herda atributos de uma classe Pessoa. polimorfismo: é a capacidade de definir métodos gerais que funcionem com várias classes, mesmo que estas requeiram implementações diferentes. I e.g. um método addItem() que sirva para qualquer tipo de lista, independentemente do que lá guardamos. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 8 / 87 Classes Classe: é uma entidade de um programa que representa: um programa/módulo, ou um template para criar um novo tipo de objectos, incluindo a descrição dos: I I tipos de dados que representam os seus atributos, e métodos que operam sobre os atributos. Exemplo: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 9 / 87 Hello World em Java Um programa em java é também uma classe: A execução de um programa Java começa sempre pelo método main(). Para executar este programa, fazer na linha de comando: khredo> javac HelloWorld.java - compilação do programa - produz um HelloWorld.class (bytecode) khredo> java HelloWorld Fernando Silva (DCC-FCUP) - emulador executa HelloWorld.class Introdução à Linguagem Java Estruturas de Dados 10 / 87 Definir classes em Java Uma classe em Java inclui: I I I atributos ou variáveis internas à classe; podem ser globais e acessíveis por todos os métodos e construtores ou locais a um método. construtores permitem inicializar os objectos no momento em que são criados; métodos que manipulam os atributos, modificando-os. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 11 / 87 Exemplo: classe Counter Implementa um simples contador que pode ser incrementado ou decrementado em uma unidade de cada vez. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 12 / 87 Definir classes em Java (2) Sintaxe: [<qualificador_classe>] class <nome_classe> [extends <superclasse>] [implements <interface_1>, interface_2>,...] { // variáveis e métodos } Uma classe pode ter um qualificador: I I I I abstract – interface, i.e. apenas define métodos abstractos (corpo vazio) final – a classe não pode ter subclasses. public – a classe pode ser instanciada ou extendida (. . .) public class <nome_classe> – só pode existir uma por ficheiro com o nome <nome_classe>.java se não se usar qualificador, assume-se a classe como friendly, i.e. equivalente a public class (default). Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 13 / 87 Noção de objecto em Java Em Java manipulamos essencialmente objectos (instâncias particulares de classes): I I fazemo-lo através de uma variável que é uma referência para o objecto através da referência podemos invocar métodos do objecto que podem alterar o seu estado Uma analogia: televisor (objecto) e comando-remoto (referência) I I I tendo o comando-remoto posso modificar o estado do objecto: aumentar o volume, mudar de canal, etc; se me deslocar na sala e quiser controlar o televisor basta-me levar comigo o comando e não o televisor; por outro lado, o facto de eu ter um comando-remoto não significa que tenha um televisor associado; Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 14 / 87 Exemplo: criação de objectos da classe Counter Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 15 / 87 Criação de um objecto em Java Criação de uma referência: Counter c; I I c é uma referência para um objecto da classe Counter; contudo c ainda não representa um objecto. O objecto é criado invocando o método construtor precedido de new. Counter c = new Counter(); I c representa agora um novo objecto do tipo Counter inicializado pelo método construtor desta classe; Ao fazermos d= c; estamos a fazer com que d referencie o mesmo objecto que c e não a cópia! Note-se que existem outros tipos básicos de dados e classes, assim como podemos criar novas classes, de onde se podem instanciar novos objectos. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 16 / 87 Métodos de classes são conceptualmente análogos a funções em outras linguagens e apenas podem existir dentro de classes; class Exemplo { ... int soma(int a, int b) { return a+b; } } só podem ser invocados através de um objecto ... Exemplo x= new Exemplo(); // objecto x ... int a= x.soma(2,3); // invocação do método de x usamos o objecto x e invocamos o método soma() (ou enviamos uma mensagem para o objecto x). Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 17 / 87 Métodos de classes: sintaxe [<qualificador>] <tipoRetorno> <nomeMétodo> ([<parâmetros>]) { } // corpo do método qualificadores: I I I I public pode ser invocado por qualquer um protected pode ser invocado apenas por métodos do mesmo package ou subclasses. private pode ser invocado apenas pelos métodos da mesma subclasse. por defeito o método é friendly, pode ser invocado por objectos de classes do mesmo package. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 18 / 87 Métodos de classes (cont.) qualificadores de segundo nível: I I I abstract sem código; apenas em classes abstractas. final método que não pode ser reescrito pela subclasse. static método da classe; na invocação não se cria uma nova instância, pode ser invocado independente do objecto métodos construtores I I são métodos especiais, com o mesmo nome da classe e usados para inicializar novos objectos. não pode ter qualificadores método main() – a classe que define o programa tem de ter um método main() para indicar onde se inicia a execução. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 19 / 87 Declaração e Atribuição Declaração de variáveis: I I I sintaxe: tipo-dados nome-variável; as variáveis têm de ser declaradas antes de ser usadas. a declaração corresponde a fazer-se reserva de memória para guardarmos o valor da variável. Atribuição: I I sintaxe: nome-variável = expressão; atribuir um valor à variável (guarda na memória associada à variável). Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 20 / 87 Qualificador static serve para referir algo independente do número de objectos criados; variáveis estáticas: class StaticField { static int x= 10; } StaticField sf1 = new StaticField(); StaticField sf2 = new StaticField(); Os atributos x dos objectos referenciados por sf1 e sf2 têm o mesmo valor (referem a mesma posição de memória). métodos estáticos: o método pode ser invocado através da classe, sem se criar o objecto. class StaticMethod { static int soma(int a, int b) {return a+b;} } int x= StaticMethod.soma(2,3); Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 21 / 87 Palavras reservadas O Java tem um conjunto de identificadores (palavras) reservadas da linguagem: abstract boolean break byte case catch char class const continue default do double else extends final finally float for goto Fernando Silva (DCC-FCUP) if implements import instanceof int interface long native new package private protected public return short static strictfp super switch synchronized Introdução à Linguagem Java this throw throws transient try void volatile while Estruturas de Dados 22 / 87 Tipos de dados básicos O Java tem apenas estes tipos de dados simples; tudo o resto são objectos: inteiros byte short int long 8 16 32 64 bits bits bits bits [−27 : 27 − 1] [−215 : 215 − 1] [−231 : 231 − 1] [−263 : 263 − 1] Vírgula flutuante (IEEE 754 floating point) float double 32 bits 64 bits [−3.4029E + 38 : +3.4029E + 38] [−1.79769E + 308 : +1.79769E + 308] Outros boolean char 8 bits 16 bits Fernando Silva (DCC-FCUP) valor booleano (true ou false) ISO Unicode char set Introdução à Linguagem Java Estruturas de Dados 23 / 87 Estruturas de Dados 24 / 87 Exemplo com tipos de dados básicos Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Operadores Aritméticos: + adição * multiplicação % módulo -- decremento / ++ subtracção divisão incremento Bits: ~ NOT binário | OR binário << shift binário esquerda & ^ >> Lógicos: ! && || NOT lógico AND lógico OR lógico AND binário XOR binário shift binário direita Relacionais ou de comparação: == igualdade != diferente < menor que <= menor ou igual que > maior que >= maior ou igual que Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 25 / 87 Divisão-inteira e Resto-da-divisão Quando dividimos inteiros, o quociente é inteiro. I I I I 18/4 dá 4 e não 4.5 y = x/2; – a divisão será inteira se x for um int. se x for float e y for int, a divisão será em virgula flutuante, mas depois o resultado é truncado para inteiro. dividir por 0 provoca um erro durante a execução O operador % calcula o resto da divisão inteira. I I 18 % 4 dá 2 59 % 5 dá 4 Aplicações do operador %: I I I obter o último dígito de um número: 12345 % 10 é 5 obter os últimos três dígitos: 734528 % 1000 é 528 verificar se um número é par: 9 % 2 é 1 e 16 % 2 é 0 Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 26 / 87 Regras de precedência entre operadores Precedência: ordem de avaliação dos operadores. a regra geral é avaliação da esquerda para a direita. I 5-2-7 é igual a (5-2)-7 que é -4 mas os operadores * / % têm maior precedência que + I I 5+2*3 é 11 5+10/2*3 é 5+5*3 que dá 20 os parentesis forçam a ordem de avaliação Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 27 / 87 Operadores de incremento/decremento operadores incremento/decremento: I I I I variavel++; variavel--; ++variavel; --variavel; ⇐⇒ ⇐⇒ ⇐⇒ ⇐⇒ variavel variavel variavel variavel = = = = variavel variavel variavel variavel + + - 1; 1; 1; 1; Cuidado com o uso destes operadores sobre variáveis no meio de expressões. Consideremos o seguinte: I I I I int x= 5, y= 3, z; x++; // incrementa x, i.e. x= x+1 --y; // decrementa y, i.e. y= y-1 z= x-- * ++y; // com que valores ficam x, y e z ? x-- diz-nos para usar primeiro o valor de x e depois decrementar em uma unidade; ++y diz-nos para primeiro incrementar y uma unidade e depois usar o seu valor. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 28 / 87 Operadores de imodificação-e-atribuição operadores modifica-e-atribui: I I I I variavel variavel variavel variavel += -= *= /= valor; ⇐⇒ variavel= variavel + valor; valor; ⇐⇒ variavel= variavel - valor; valor; ⇐⇒ variavel= variavel * valor; valor;⇐⇒ variavel= variavel / valor; Exemplos: I I I x -= 1; ⇐⇒ x--; ⇐⇒ x= x-1; y /= 2; ⇐⇒ y = y/2; x *= y+2;⇐⇒ x= x*(y+2); Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 29 / 87 Instruções de controle de fluxo (ou de decisão) if-else if (a>b) a++; else b++; ?: (a>b) ? a++; : b++; switch-case if (condição) { codigo-se-condição-true; } else { código-se-condição-false; } Fernando Silva (DCC-FCUP) switch (variável) { case valor1: { bloco-código1; break; } case valor2: { ... } default: { código-por-defeito; break; } } Introdução à Linguagem Java Estruturas de Dados (condição) ? código-se-true; : código-se-false; 30 / 87 Instruções de ciclo: while Estrutura geral: inicializa; while (condição) { bloco_instruções; next; } Fernando Silva (DCC-FCUP) Um exemplo: método para verificar se um inteiro é primo. Introdução à Linguagem Java Estruturas de Dados 31 / 87 Instruções de ciclo: for Estrutura geral: for (inicialização; condição-paragem; next) { bloco_instruções; } Um exemplo: método para verificar se um inteiro é primo. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 32 / 87 Instruções de ciclo: do-while Estrutura geral: inicializa; do { bloco_instruções; next; } while (condição); Fernando Silva (DCC-FCUP) Um exemplo: método para verificar se um inteiro é primo.. Introdução à Linguagem Java Estruturas de Dados 33 / 87 Strings em Java as strings são objectos da classe String uma string é uma sequência de caracteres vista como uma unidade. criação de strings: I I I String cor1= “vermelho”; – inicializada. String mistura= “vermelho” + “amarelo”; – inicializada. String cor2; – não inicializada. criação/inicialização invocando métodos construtores: I I cor2= new String(“verde”); cor3= new String(“”); – inicializa com string vazia o operador + funciona como concatenador de strings I cor2= “Hello” + “World” + cor1; segue-se um exemplo do uso de construtores para inicializar um objecto String. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 34 / 87 Exemplo com Strings Diferentes maneiras de criar objectos do tipo String: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 35 / 87 Strings como vectores de caracteres As strings não são vectores do tipo array do Java, mas, podem ser vistas como vectores: cada caracter é um char, mas como aceder a cada um dos caracteres? nome.charAt(0) ou nome.charAt(5) e se pretender imprimir todos? for(int c=0; c < nome.length(); c++) System.out.print(nome.charAt(c)); posso transformar um vector de caracteres numa string e vice versa? I I char n[]= nome.toCharArray(); converte a string em vector. String nova= Arrays.toString(n); converte o vector n[] em string. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 36 / 87 Comparação de Strings Como comparar se duas strings são iguais? I usar o método equals() e não o habitual operador “==”. Dadas duas strings s1 e s2: I I s1 == s2 apenas compara as referências dos dois objectos para ver se se referem à mesma instância. s1.equals(s2) compara por ordem os caracteres das duas strings. O método equals() compara duas strings I as duas strings serão iguais se tiverem os caracteres iguais, pela mesma ordem. O método int n= s1.compareTo(s2) compara lexicograficamente as strings s1 e s2 I I I n<0, se s1 precede s2 n==0, se forem iguais n>0, se s1 vem a seguir a s2 Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 37 / 87 Comparação de Strings Exemplos: String s1= ‘‘Hello’’; String s2= ‘‘Hello’’; String s3= ‘‘Good-bye’’; String s4= ‘‘HELLO’’; s1.equals(s2) --> s1.equals(s3) --> s1.equals(s4) --> s1.equalsIgnoreCase(s4) --> true false false true Experimentar num programa: System.out.print(s1+" equals "+s2+"-->"s1.equals(s2)); (true) e System.out.print(s1+"=="+s2+"-->" s1 == s2); (false) Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 38 / 87 Input e Output em Java As funcionalidades de I/O do Java estão definidas na API: java.io. A leitura e escrita faz-se através de canais (streams) que podem representar um qualquer periférico físico. Os canais podem ser: Byte streams : leitura e escrita sob a forma de bytes; Character streams : leitura e escrita sob a forma de carateres. A classe System, definida em java.lang, inclui muitas definições de sistema, nomeadamente 3 canais: in, out, e err. I I I InputStream System.in – objecto que representa o standard input stream (por defeito o teclado); PrintStream System.out – objecto que representa o standard output stream (por defeito a consola); PrintStream System.err – objecto que representa o standard error stream (consola). Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 39 / 87 A classe Scanner Fornece métodos de parsing de tipos primitivos e Strings. Simplifica muito o processamento do input vindo de: I I I um canal de leitura (tipo InputStream) Scanner stdIn= new Scanner(System.in); // lê do teclado uma String Scanner strIn= new Scanner(line); // line é uma string ou de um ficheiro File nf= new File(nomeFich); Scanner fileIn= new Scanner(nf); // lê do ficheiro a classe Scanner lê do canal de leitura e divide-o em palavras que são strings separadas por caracteres especiais, os delimitadores. I I o método useDelimiter(expressao) permite especificar, através de uma expressão regular, o modo como se pretende separar o input em palavras. Exemplo: scanner.useDelimiter("\r\n") Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 40 / 87 Classe Scanner - métodos Para se poder usar a classe Scanner é necessário declarar no programa: import java.util.Scanner; ou import java.util.*; Alguns métodos relevantes desta classe: hasNext() next() hasNextLine() nextLine() hasNextType() nextType() Fernando Silva (DCC-FCUP) true se e só se existir mais uma palavra no input retorna a próxima palavra (String) do input true se e só se o input tiver mais uma linha de texto retorna a próxima linha de texto do input true se e só se a próxima palavra for do tipo Type, onde Type pode ser qualquer tipo básico: Int, Float, Double... retorna a próxima palavra convertida para o tipo básico definido por Type. Introdução à Linguagem Java Estruturas de Dados 41 / 87 Scanner: leitura a partir de uma String Processa a leitura a partir da String e aplica os separadores definidos por useDelimiter(): Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 42 / 87 Scanner: leitura a partir do teclado Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 43 / 87 Estruturas de Dados 44 / 87 Scanner: leitura a partir de um ficheiro Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Output formatado: classe Formatter O Java a partir da versão 5.0 admite output formatado ao estilo do printf do C. usar a package java.util.Formatter e o método format() da classe String: String fmt= String.format(‘‘pi = %5.3f\n’’); para escrever formatado, usar: double pi= Math.PI; System.out.printf(fmt, pi); ou System.out.printf("pi= %5.3f\n", pi); Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 45 / 87 Formatação de texto com printf() Sintaxe do método printf() é: System.out.printf ("string formato", parâmetros) Uma string de formato contém “encaixes” para inserir os valores dos parâmetros: I I I I I I %d %x %o %f %s %c - inteiro base 10 inteiro base hexadecimal inteiro base octal número real ou em vírgula flutuante string caracter o printf() não faz a mudança de linha é necessário incluir o caracter ‘\n’ (newline) na string de formato no ponto onde quisermos mudar de linha. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 46 / 87 Formatos especiais (inteiros) %Wd - inteiro com W caracteres de largura, alinhado à direita. %-Wd - inteiro com W caracteres de largura, alinhado à esquerda. Output: 1 2 3 2 4 6 3 6 9 Fernando Silva (DCC-FCUP) 4 8 12 5 10 15 6 12 18 7 14 21 8 16 24 9 18 27 10 20 30 Introdução à Linguagem Java Estruturas de Dados 47 / 87 Formatos especiais (reais) %.Df - no real, arredondado para D casas decimais. %W.Df - no real, com W caracteres e D casas decimais. %-W.Df - no real, com W caracteres alinhados à esquerda e D casas decimais. Exemplo: double media= 13.172585; System.out.printf("Media: %.1f\n", media); System.out.printf("Media mais precisa: %8.3f\n", media); Output: Media: 13.2 Media mais precisa: 13.173 Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 48 / 87 Exemplo: uso de printf Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 49 / 87 Vectores simples (arrays) em Java Os arrays são objectos que agrupam sob um mesmo nome um conjunto de variáveis numeradas de um mesmo tipo (primitivo ou objecto). As variáveis de um array são sempre indexadas a partir do zero. criar uma referência x para um “vector de inteiros”; I I int[] x; ou int x[]; o operador new permite reservar espaço em memória para o vector x[] (dimensionando-o): I x = new int[10]; – cria efectivamente o vector e guarda a sua localização em x. x[0]= 23 x[1]= 15 Fernando Silva (DCC-FCUP) x[2]= 25 ... Introdução à Linguagem Java Estruturas de Dados 50 / 87 Vectores simples em Java (2) Ao trabalharmos com arrays é necessário ter atenção a possíveis excepções que sejam geradas e indiciadoras de situações de erro, e.g: I I NullPointerException – tentar usar o vector sem o criar; ArrayIndexOutOfBounds – aceder ao vector fora dos limites, e.g. int v[]= new int[4]; // vector com 4 elementos v[4]= 5; // aborta com ArrayIndexOutOfBoundsException // v[4] já seria o 5o elemento! No Java, todos os vectores têm associado uma variável atributo length, e.g. I v.length dá a dimensão (ou capacidade) do vector. Como re-dimensionar um vector? Apenas por cópia para novo: I int nv[]= Arrays.copyOf(v, 2*v.length); Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 51 / 87 Vectores simples em Java (3) Podemos escrever os elementos de um vector com apenas um print? produz duas linhas de output: É possível comparar vectores com apenas uma instrução de comparação (==)? Não! I I é necessário fazer um ciclo a comparar os elementos, ou usar o método Arrays.equals() Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 52 / 87 Exemplos do uso de vectores Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 53 / 87 Clonagem de vectores Clonagem de vectores (cria uma cópia separada do vector!): Ilustração dos vectores após clonagem: x[] e xCopia[] são duas referências para o mesmo objecto (não existe propriamente uma cópia). x[] e xClone[] são dois objectos em que o segundo é de facto a cópia do primeiro (por clonagem). Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 54 / 87 Vectores como parâmetros e retorno de métodos Um método pode ter parâmetros na chamada que são vectores e pode dar como resultado um vector. Exemplo: escrever um método em que dados 2 vectores de igual tamanho, retorna um vector com a soma dos dois vectores. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 55 / 87 Vectores multimensionais (matrizes) em Java Os vectores podem ser multi-dimensão (e.g. as matrizes). Por exemplo: int v[][]= new int[4][4]; // matriz bi-dimensional 4x4 int u[][][]= new int[4][4][4]; // tri-dimensional Exemplo: Multiplicação de uma matriz a[N][M] por um vector u[M] para dar v [N]: i.e. vi = Fernando Silva (DCC-FCUP) M−1 X j=0 aij × uj (0 ≤ i < N) Introdução à Linguagem Java Estruturas de Dados 56 / 87 Multiplicação de matriz por vector Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 57 / 87 Triângulo de Pascal O triângulo de Pascal pode ser visto como uma matriz triangular inferior: 1 1 1 1 1 1 1 2 3 4 5 ou 1 3 6 10 1 4 10 1 5 1 1 1 1 1 1 1 1 2 1 3 3 1 4 6 4 5 10 10 1 5 <-<-<-<-<-1 <-- lin lin lin lin lin lin 0 1 2 3 4 5 Cada valor é a soma dos dois valores mais próximos da linha anterior. A representação corresponde a uma matriz triangular inferior. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 58 / 87 Triângulo de Pascal Método para calcular as linhas do Triângulo de Pascal, usando uma matriz apenas dimensionada triangularmente: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 59 / 87 Dimensionamento matriz triangular inferior Ilustração da matriz triangular inferior que representa o triângulo de Pascal (só estamos a reservar memória para o número correcto de elementos na linha): Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 60 / 87 Instruções break, continue e return break - sai do bloco de código corrente, normalmente um ciclo ou switch, continuando a execução na instrução a seguir ao ciclo ou switch. continue - é a instrução dual do break, servindo para se ignorar as instruções da iteração corrente de um ciclo, passando-se para a iteração seguinte. labels - etiquetas que podem ser associadas a break e continue, marcando a posição no código para onde transita a execução. return - força a saída do corpo de um método com retorno de uma variável com o tipo de dados de retorno do método. Se o método não retornar nada, i.e. tiver tipo void, a execução do método termina na última instrução (não tem instrução de return). Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 61 / 87 Exemplo com labels, breaks e continues Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 62 / 87 Constantes e Tipos Enumerados de Dados Uma constante em Java tem de ser definida no âmbito de uma classe, como um dos seus atributos e declarada como static final. Exemplos: I I I I static final int N=100; static final float PI= 3.1415; Por convenção, o nome de uma constante é todo em maiúsculas. Só existe uma cópia de um atributo estático de uma classe, independentemente do número de instâncias que possam ser criadas. Um atributo que seja do tipo enumerado, enum, apenas pode tomar os valores de um conjunto de valores especificado. I I Sintaxe: [modificador] enum <nome> {val0, val1, ..., valN-1}; o modificador pode ser public, private ou protected, ou vazio. Exemplo: public enum Dia {SEG, TER, QUA, QUI, SEX, SAB, DOM}; Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 63 / 87 Exemplo do uso de tipos enumerados Classe que exemplifica o uso de uma variável do tipo enumerado para representar dias da semana: O output que se obtém é: Inicialmente d ee SEG Depois passou para QUA Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 64 / 87 Objectos genéricos em Java Em Java, só temos referências a objectos e 8 tipos básicos de dados. Em Java, todos os objectos são casos particulares de um tipo mais geral chamado Object. Object permite a utilização de variáveis capazes de conter uma referência para qualquer tipo de objecto. O objecto t fica com a capacidade de se referir a qualquer coisa (tipo mais geral). A redução do âmbito do tipo Object para um outro mais específico, obriga a fazer uma conversão de tipos (type-cast). Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 65 / 87 Wrappers para tipos primitivos Os objectos genéricos permitem definir classes genéricas, i.e. I classes que podem conter qualquer tipo de objectos. Por exemplo, podemos pensar numa classe que represente uma lista que possa conter qualquer objecto Java. Contudo, isso impede que se tenha nessa lista valores do tipo int ou de outro tipo básico. Para ultrapassar esta dificuldade, o Java fornece classes especiais (wrapper classes) que encapsulam em objectos os tipos primitivo. Exemplos: I I I classe Integer – cada objecto contém um int classe Boolean – cada objecto contém um boolean etc. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 66 / 87 Wrapper classes (cont.) Wrapper Class Byte Short Integer Long Float Double Character Boolean Fernando Silva (DCC-FCUP) Construtor Byte(byte v) Short(short v) Integer(int v) Long(long v) Float(float v) Double(double v) Character(char v) Boolean(boolean v) Método acesso byte byteValue() short shortValue() int intValue() long longValue() float floatValue() double doubleValue() char charValue() boolean booleanValue() Introdução à Linguagem Java Estruturas de Dados 67 / 87 Wrapper classes (cont.) O Java 5.0 escondeu o uso das wrapper-classes, simplificando a forma como se lidam com objectos numéricos, Number (e.g. Integer, Float, ...) Permite conversões implícitas, designadas por autoboxing, que convertem um tipo básico num objecto Number Também permite o inverso, unboxing, i.e. sempre que for esperado um tipo básico numa expressão, converte automaticamente o objecto Number nesse tipo. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 68 / 87 Exemplo: autoboxing e Unboxing Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 69 / 87 A classe Arrays A implementação de vectores em Java tem por base a classe Arrays que integra o pacote java.util. o atributo length diz-nos a dimensão do vector alguns métodos importantes da classe copyOf(v,newSize) copyOfRange(v,i0,i1) equals(v1,v2) fill(v,val) sort(v) toString(v) Fernando Silva (DCC-FCUP) retorna uma cópia do v com tamanho newSize retorna uma cópia da porção de v compreendida entre os indices i0 e i1 retorna true se os dois vectores tiverem os mesmos elementos preenche todos os elementos do vector v com o valor val ordena os elementos do vector retorna uma String com a representação do vector v Introdução à Linguagem Java Estruturas de Dados 70 / 87 Problema 1: Múltiplos Contadores Problema 1: Escrever um método digitoMaisFrequente() que retorne o dígito que ocorre mais vezes num dado número. Exemplo: o número 3435667323 contém: I I 1 (2), 4 (3), 1 (4), 1 (5), 2 (6) e 1 (7) digitoMaisFrequente(3435667323) retorna 3 se existir um empate, deve mostrar o menor dígito. Sugestão: I I I usar um contador por cada dígito (vector com 10 contadores) d=n%10 dá o dígito das unidades; n=n/10 retira dígito das unidades Exemplo 669260267 Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 71 / 87 Problema 1: Múltiplos Contadores (solução) Ver solução completa na página dos apontamentos: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 72 / 87 Problema 2: Histogramas Problema 2: Escrever um método void histograma(int notas[]) que, recebendo como parâmetro um vector de classificações, dados como valores inteiros, produza um histograma de estrelas (*) que indique o número de alunos que obtiveram uma determinada classificação (supor apenas os registos de 0 a 20. Exemplo: I I dados 12 13 12 17 14 14 18 15 13 15 12 15 deve produzir: 12: *** 13: ** 14: ** 15: *** 17: * 18: * Sugestão: solução parecida com anterior, mas com 21 contadores! Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 73 / 87 Estruturas de Dados 74 / 87 Problema 2: Histogramas (solução) Solução completa nos apontamentos: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Problema 3: Vectores de Objectos Em muitas situações, a informação que precisamos de guardar não se traduz por apenas um valor, mas sim por um conjunto de valores agregados que caracterizam um objecto/entidade. Exemplo simples: classe para representar um ponto no plano Suponhamos que pretendemos ler n pontos no plano e determinar qual deles está mais próximo da origem. Como fazer? Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 75 / 87 Estruturas de Dados 76 / 87 Problema 3: Vector de Pontos Leitura dos pontos para o vector: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Problema 3: Vector de Pontos distancia a um ponto: calcular mais próximo da origem: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 77 / 87 Prob 4: Cobrador de Impostos (Vector de Objectos) Problema 4: Foram-lhe fornecidos dados sobre um conjunto de empresas, nomeadamente, para cada empresa, foi-lhe dada informação sobre: O seu número de indentificação fiscal (NIF) O nome da empresa A sua área de actividade económica O código da área de actividade económica Os rendimentos declarados no último ano fiscal A sua tarefa consiste em ler os dados e apresentar o total de rendimentos por cada área de actividade económica. A informação deve aparecer ordenada por ordem crescente do código de área económica. Nota: ver solução na página dos apontamentos. Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 78 / 87 Problema 4: Cobrador (classe Empresa) Representar a informação sobre uma empresa como uma classe: Devemos depois usar um vector de objectos desta classe: Empresa emp[]= new Empresa[N] Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 79 / 87 Estruturas de Dados 80 / 87 Problema 4: Cobrador (método main) No main() lemos os dados e escrevemos a solução: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Problema 4: Cobrador (método leDadosEmpresa) A leitura de dados relativos a uma empresa é feita na classe Empresa pelo método: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 81 / 87 Problema 5: Escrita de Números em Texto Problema 5: Dado um número n, 0 <= n < 1000000, implemente um método que escreva em texto o número. Exemplos: I I I I I I I 100 = cem 105 = cento e cinco 1000 = mil 12345 = doze mil trezentos e quarenta e cinco 10045 = dez mil e quarenta e cinco 10000 = dez mil 10020 = dez mil e vinte Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 82 / 87 Problema 5: Sugestões Como lidar com números menores que 100, i.e. números com dois dígitos N = d1 d2 ? Se d1 for 0? I I I números de 0 a 9 i.e. temos strings de “zero” a “nove” String unidades[]={"zero",...,"nove"}; indexamos o vector com o valor de d2 Se d1 for 1? I I números de 10 a 19 i.e. temos strings de “dez” a “dezanove” String dez_dezanove[]={"dez",...,"dezanove"}; Se d2 for 0? I I temos números números 20, 30, ..., 90. String dezenas[]={"","","vinte",...,"noventa"}; Caso geral com os dois dígitos I I temos números números como 25, 33, ... dezenas[d1] + " e " + unidades[d2] Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 83 / 87 Estruturas de Dados 84 / 87 Problema 5: método converte2() Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Problema 5: método converte3() Como converter números menores que 1000? Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 85 / 87 Estruturas de Dados 86 / 87 Problema 5: método converte6() Como converter números menores que 1000000? Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Problema 5: método main() Leitura do input e escrita: Fernando Silva (DCC-FCUP) Introdução à Linguagem Java Estruturas de Dados 87 / 87