Disciplina: Linguagem de Programação Notas de Aula 07: vetores de objetos e coleções Objetivos da aula: Entender a sintaxe de vetores em Java Compreender o uso do vetor como um objeto Uso das coleções em Java Recordando... Na aula passada você aprendeu que é possível declarar supertipos e instanciar subtipos. Entendeu, também, que empregar este recurso traz benefícios para reutilização de objetos quando modelados adequadamente. Nesta aula você aprenderá a utilizar o conceito de vetores em Java tendo em vista a programação para interfaces. Vetores de tipos primitivos Em Java, como toda linguagem de programação, é possível declarar vetores de tipos de primitivos. A sintaxe é: <tipo> [] <nomeVetor> = new <tipo>[TAMANHO]; Por exemplo, um vetor de inteiros para 10 elementos: int [] idadeAlunos = new int [10]; Um vetor é um caso especial de uma matriz, então: float [][] notasAlunos = new float [10][3]; //10 alunos, Av1,Av2,Av3 Em Java, matriz (e vetores) são objetos. Um atributo (público e final) pode ser utilizado para descobrir o tamanho do vetor: idadeAlunos.length; Uma estrutura de repetição para leitura dos dados de um vetor ficaria assim: Professores: José Gomes de Carvalho Júnior, D.Sc. Pablo Rangel, D.Sc. Disciplina: Linguagem de Programação package exemplos.matrizes; import java.util.Scanner; public class VetorPrimitivo { public static void main(String[] args) { Scanner teclado = new Scanner(System.in); int [] idadeAlunos = new int[10]; for (int i=0; i<idadeAlunos.length; i++){ System.out.println("Entre com a idade do " + (i+1) + "º aluno: "); idadeAlunos [i] = teclado.nextInt(); } } } Para uma matriz, ficaria assim: package exemplos.matrizes; import java.util.Scanner; public class MatrizPrimitivo { public static void main(String[] args) { Scanner teclado = new Scanner(System.in); float [][] notasAlunos = new float[10][3]; for (int i=0; i<notasAlunos.length; i++){ for (int j=0; j<3; j++){ System.out.println("Entre com a nota da AV" + (j+1) + " do " + (i+1) + "º aluno: "); notasAlunos[i][j] = teclado.nextInt(); } } } } A inicialização de uma matriz (e um vetor) pode ser feita assim: float [][] notasAlunos = { {10f,8.5f,3.5f},{6f,7.8f,9f} }; //M 2X3 int [] idadeAlunos = { 27, 22, 30, 45}; //V 4X1 Vetores de objetos A declaração de vetores de objetos segue a mesma linha. Se observarmos o método main, veremos que existe um argumento que é um vetor de Strings (lembrando que a String é uma classe) que tem como valor os parâmetros passados na execução do programa pelo terminal. public static void main(String[] args) { Vetores de objetos em Java são declarados de forma muita parecida. Por exemplo, para declarar um vetor com 10 engenheiros, basta fazer: Professores: José Gomes de Carvalho Júnior, D.Sc. Pablo Rangel, D.Sc. Disciplina: Linguagem de Programação Engenheiro [] engenheiros = new Engenheiro[10]; Cada objeto deve ser instanciado individualmente... for (int i=0; i< engenheiros.length; i++){ engenheiros [i] = new Engenheiro(); } ... e deve ser acessado através de uma estrutura de controle ou diretamente pelo índice: for (int i=0; i< engenheiros.length; i++){ engenheiros [i] = new Engenheiro(); engenheiros [i].setCrea(String.valueOf(i)); } engenheiro[2].toPrint(); A partir do Java 5, o comando for estendido tornou o código mais elegante, dispensando o uso de uma variável de controle e aproveitando a dimensão do vetor: for (Engenheiro engenheiro : engenheiros) { engenheiro.toPrint(); } Listas e coleções em Java Apesar de funcional, o uso de vetores na forma convencional em Java não se aproveita da imensa biblioteca de estruturas de dados que a linguagem dispõe. As coleções em Java (interface Collection) são classes que implementam os métodos para inicialização, busca, remoção, etc. para um conjunto de dados. Por exemplo, as classes Vector e ArrayList tem por objetivo fornecer uma api para manipulação e dados em uma lista. Esses objetos não necessitam que um tamanho seja especificado, pois ambos tratam de manipular a área alocada automaticamente (o ArrayList aumenta sempre 50% de sua capacidade, enquanto que o Vector 100%). A classe ArrayList (java.util.ArrayList) é útil para a grande maioria dos casos e funciona como um objeto qualquer: ArrayList listaEngenheiros = new ArrayList(); Professores: José Gomes de Carvalho Júnior, D.Sc. Pablo Rangel, D.Sc. Disciplina: Linguagem de Programação Para adicionar um objeto a lista, basta fazer: Engenheiro eng = new Engenheiro(); listaEngenheiros.add(eng); Para percorrer a lista, faça: for (int i=0; i< listaEngenheiros.size(); i++){ Engenheiro engenheiro = (Engenheiro)listaEngenheiros.get(i); engenheiro.toPrint(); } Perceba que a classe ArrayList possui um método size() que retorna a quantidade de elementos existentes. A classe ArrayList pode ser empregada para uma gama de classes de domínio sem necessidade alguma de implementar a estrutura de dados. Essa generalidade advém do fato de que a classe trabalha com objetos da classe Object não importando, portanto, o tipo utilizado. Nesse sentido, observe que foi necessário fazer um cast, pois o método get(índice) retornou um objeto da classe Object. A classe ArrayList utiliza o recurso Generics, o que nos permite evitar o cast: ArrayList<Engenheiro> listaEngenheiros = new ArrayList(); Engenheiro eng = new Engenheiro (); eng.setCpf("10203049"); listaEngenheiros.add(eng); for (int i=0; i< listaEngenheiros.size(); i++){ Engenheiro engenheiro = listaEngenheiros.get(i); engenheiro.toPrint(); } Um pouco mais sofisticado A maneira como estamos percorrendo a lista presume uma lista sequencial, com alocação contigua de memória, uma vez que estamos obtendo os valores índice por índice através do métodos get(indice). Na verdade, podemos utilizar um nível maior de abstração e, ao invés de especificar o elemento que queremos, podemos solicitar o próximo elemento sem especificar diretamente como fazê-lo - em uma lista sequencial, o elemento imediato é o próximo índice; em uma lista encadeada, o ponteiro do próximo nó. Para alcançarmos isso, iremos utilizar um objeto da classe Iterator. Para isso, faça: Professores: José Gomes de Carvalho Júnior, D.Sc. Pablo Rangel, D.Sc. Disciplina: Linguagem de Programação Collection<Engenheiro> listaEngenheiros = new ArrayList(); Engenheiro eng = new Engenheiro (); eng.setCrea("10203049"); listaEngenheiros.add(eng); Iterator <Engenheiro>iterator = listaEngenheiros.iterator(); while(iterator.hasNext()){ Engenheiro engenheiro = iterator.next(); engenheiro.toPrint(); } O iterator que nós usamos é um atributo da classe ArrayList. O iterator também é uma interface com métodos básicos para percorrer uma estrutura de dados. É a classe ArrayList (sua classe mãe AbstractList, na verdade) que assumiu um contrato de implementar os métodos do iterador (hasNext(), next(), etc.). Repare que declaramos a lista de engenheiros (listaEngenheiros) pelo supertipo, isto é, a interface Collection. E daí? Se, em algum momento, decidirmos que a estrutura de dados ArrayList não está adequada, podemos mudar apenas na instanciação do objeto. Que tal utilizar uma lista encadeada? Basta alterar para o objeto da classe LinkedList. Collection<Engenheiro> listaEngenheiros = new LinkedList(); Professores: José Gomes de Carvalho Júnior, D.Sc. Pablo Rangel, D.Sc. Disciplina: Linguagem de Programação Exercícios 1) Faça um programa em Java que leia dos dados de uma matriz quadrada e imprima a diagonal principal da matriz. Utilize a declaração convencional. 2) Faça um programa em Java que leia dos dados de uma matriz quadrada e imprima a diagonal secundária da matriz. Utilize a declaração convencional. 3) Faça um programa em Java que leia 10 elementos inteiros e armazene em um ArrayList. O conteúdo do array deve ser o índice de forma decrescente. Implemente a interface Comparator. Utilize o método sort() e imprima o resultado. 4) Observe o modelo abaixo: Implemente as classes obedecendo à hierarquia do diagrama. A interface Pontuacao define o método calcularPontos(), que é especificamente implementado em cada classe, obedecendo às seguintes regras de negócio: Professores: José Gomes de Carvalho Júnior, D.Sc. Pablo Rangel, D.Sc. Disciplina: Linguagem de Programação a) Os pontos de um cartão de prova são: o número de acertos multiplicado por dois, menos o número de erros; b) Os pontos de um clube de futebol são o número de vitórias multiplicado por três, mais o número de empates; c) Os pontos de um clube de investimentos são o número de sócios multiplicado pelo investimento médio. A classe Principal deve criar um array de três objetos, instanciando um objeto de cada classe passando os parâmetros adequados ao construtor. A seguir, deve enviar uma mensagem ao objeto pedindo para que este calcule a quantidade de pontos e deve imprimir esse valor recebido. Utilize um ArrayList e o iterator. Professores: José Gomes de Carvalho Júnior, D.Sc. Pablo Rangel, D.Sc.