© ELFS 71
• A Java API contém diversas classes para a manipulação de estruturas de dados. A estrutura de dados mais simples é o vetor ( array ).
• Um vetor é um agrupamento de valores de um mesmo tipo primitivo ou um agrupamento de objetos de uma mesma classe.
• Cada elemento de um vetor armazena um valor. Os elementos de um vetor são referenciados por meio de um índice. O primeiro elemento tem sempre o índice 0 (zero). Portanto, para um vetor de n
elementos, os índices variam de 0 a n-1.
• Em Java, vetores têm tamanho fixo e, uma vez criados, não podem ser redimensionados. O campo length contém o tamanho do vetor.
• Um vetor é um objeto da classe Object, ou seja, a criação de um vetor cria, implicitamente, um objeto da classe java.lang.Object.
v[0] v[1] v[2] v[3] v[4] v[5]
v
• Vetores são declarados utilizando-se colchetes. Exemplo: int x[];
• Ao declarar vetores, os colchetes podem ser colocados no início da declaração para indicar que todos os identificadores são vetores.
Exemplo: double a[], b[], c[];
pode ser escrito como: double[] a, b, c;
• Como em qualquer classe, apenas a declaração do vetor não cria o objeto. A declaração só cria uma referência (ponteiro) para o vetor. A memória a ser utilizada pelo vetor é alocada ou pela instrução new ou pela inicialização do vetor.
Exemplo:
• O acesso a um elemento de índice fora do intervalo declarado para o vetor gera uma exceção (erro em tempo de execução).
• Depois de criado, o vetor possui atributos e métodos como qualquer outro objeto.
3. Vetores e Matrizes 3. Vetores e Matrizes
char letra[] = new char[26]; // vetor de 26 valores do tipo char Ponto p[] = new Ponto[3]; // vetor de 3 objetos da classe Ponto int x[] = {2,8,3,5,1}; // declaração e inicialização
© ELFS 73
• Vetores podem ser parâmetros de métodos. Na chamada ao método, somente o nome do vetor é passado. Vetores, como são objetos (e, portanto, o nome do vetor é um ponteiro) são sempre passados por referência.
Exemplo:
public class MeuVetor {
public void mostrarValores(String nome, int vetor[]) {
for (int i = 0; i < vetor.length; i++)
System.out.println(nome + "[" + i + "] = " + vetor[i]);
} }
public class ProgVetor {
public static void main(String[] args) {
int x[] = {1,2,3,4,5};
MeuVetor mv = new MeuVetor();
mv.mostrarValores("x",x);
} }
MeuVetor.java
ProgVetor.java
A saída será:
x[0] = 1 x[1] = 2 x[2] = 3 x[3] = 4 x[4] = 5
Recordando:
• Existem duas maneiras de passar parâmetros para os métodos: a passagem por valor e a passagem por referência.
• Quando um parâmetro é passado por valor, uma cópia do valor do parâmetro é passada para o método chamado. O método chamado trabalha exclusivamente com a cópia. As alterações feitas na cópia pelo método chamado não afetam o valor do parâmetro original.
• Quando um parâmetro é passado por referência, o método chamado trabalha diretamente com o parâmetro original e, portanto, as
alterações feitas pelo método chamado afetam o parâmetro original.
• Em Java, o programador não escolhe o tipo de passagem de
parâmetros: valores primitivos são passados por valor e referências a objetos são passados por referência.
• Notar que:
• Vetores são passados por referência (pois o nome do vetor é uma variável de referência)
• Elementos de vetores de tipos primitivos são passados por valor.
3. Vetores e Matrizes 3. Vetores e Matrizes
© ELFS 75
• Após a criação, os elementos do vetor devem ser inicializados, antes de serem usados (na criação, os elementos são inicializados com o valor padrão). Existem diferentes modos de declaração e de
inicialização de vetores.
Exemplo:
String nome[];
int n = 3;
nome = new String[n];
nome[0] = "Zé";
nome[1] = "Jó";
nome[2] = "Lu";
String nome[] = new String[3];
nome[0] = "Zé";
nome[1] = "Jó";
nome[2] = "Lu";
String nome[] = {"Zé","Jó","Lu"}; Declara e inicializa. O tamanho do vetor é dado pelo número de valores na lista de inicialização. A alocação de memória é feita durante a inicialização.
Declara primeiro e inicializa depois. O tamanho do vetor é dado na declaração. A alocação de memória é feita pela declaração. A inicialização ocorre depois da memória ter sido alocada.
Declara somente o ponteiro. Em seguinda cria os objetos. Notar que entre a declaração do ponteiro e a criação dos objetos, o tamanho do vetor pode ser lido, atribuído ou calculado. Com isso, o vetor pode ter exatamente o tamanho
necessário. A inicialização ocorre depois da memória ter sido alocada.
Exemplo:
import javax.swing.JOptionPane;
public class LerTamanhoVetor {
public static void main(String[] args) {
int v[];
String sTam;
int tam;
sTam = JOptionPane.showInputDialog("Tamanho do vetor");
tam = Integer.parseInt(sTam);
// Construir o vetor do tamanho desejado v = new int[tam];
for (int i = 0; i < tam; i++) v[i] = 2*(i + 1);
MeuVetor mv = new MeuVetor();
mv.mostrarValores("v",v);
} }
3. Vetores e Matrizes 3. Vetores e Matrizes
LerTamanhoVetor.java
Com tamanho = 5, a saída será:
v[0] = 2 v[1] = 4 v[2] = 6 v[3] = 8 v[4] = 10
© ELFS 77
import java.util.*;
public class ExemploVetor {
public static void lerVetor(int v[]) {
Scanner in = new Scanner(System.in);
for (int i = 0; i < v.length; i++) {
System.out.print("v[" + i + "] = ");
v[i] = in.nextInt();
} }
public static int somarVetor(int v[]) {
int soma = 0;
for (int i = 0; i < v.length; i++) {
soma = soma + v[i];
}
return soma;
}
ExemploVetor.java
Outro exemplo:
public static void mostrarVetor(int v[]) {
System.out.print("[");
for (int i = 0; i < v.length; i++) {
System.out.print(v[i]);
if (i < v.length-1)
System.out.print(", ");
}
System.out.println("]");
}
public static void main (String [] args) {
int n,x[];
Scanner in = new Scanner(System.in);
System.out.print("Tamanho do vetor: ");
n = in.nextInt();
x = new int[n];
lerVetor(x);
mostrarVetor(x);
int s = somarVetor(x);
System.out.println("Soma = " + s);
} }
3. Vetores e Matrizes 3. Vetores e Matrizes
Se o vetor lido for:
x = [2, 4, 6, 8, 10]
a saída será:
Soma = 30
© ELFS 79
• Exercício. Considere que um vetor v contém o número de notas dos alunos de PC-2 agrupadas em categorias, ou seja: v[0] contém o número de notas de 0.0 a 0.9, v[1] contém o número de notas de 1.0 a 1.9, v[2] contém o número de notas de 2.0 a 2.9, assim por diante, até v[10], que contém o número de notas 10. Mostrar a distribuição de notas por meio de um gráfico de barra de asteriscos (*).
public class GraficoBarras {
public void mostrarGrafico(int vetor[]) {
for (int i = 0; i < vetor.length; i++) {
if (i < 10)
System.out.printf("%3.1f-%3.1f: ",(i+0.0),(i+0.9));
else
System.out.printf("%7.1f: ",10.0);
for (int j = 0; j < vetor[i]; j++) System.out.print("*");
System.out.println();
} } }
GraficoBarras.java
import javax.swing.JOptionPane;
public class DistribuicaoNotas {
public static void main(String[] args) { int v[] = new int[11];
String s;
int nAlunos, nota, categ;
for (int i = 0; i < 11; i++) v[i] = 0;
s = JOptionPane.showInputDialog("Numero de alunos");
nAlunos = Integer.parseInt(s);
// Ler as notas dos alunos e distribuir nas categorias for (int i = 0; i < nAlunos; i++) {
s = JOptionPane.showInputDialog("Nota do aluno " + (i+1));
nota = Integer.parseInt(s);
categ = nota / 10;
v[categ]++;
}
GraficoBarras gb = new GraficoBarras();
gb.mostrarGrafico(v);
} }
3. Vetores e Matrizes 3. Vetores e Matrizes
DistribuicaoNotas.java
© ELFS 81
Vetores Multidimensionais
• Vetores podem ter diversas dimensões. Um vetor bidimensional é também conhecido como matriz.
• É possível construir vetores multidimensionais não-retangulares em Java.
• Como um vetor pode conter qualquer objeto, para definir vetores multidimensionais basta definir um vetor de vetores.
Exemplos:
int v[][] = new int[2][];
v[0] = new int[2];
v[1] = new int[2];
Vetor retangular 2x2 (ou matriz de 2 linhas e 2 colunas).
int vet[][] = new int[3][];
vet[0] = new int[2];
vet[1] = new int[4];
vet[2] = new int[3];
Um vetor bidimensional não retangular.
int m[][] = {{1,2},{3,4}}; Corresponde à matriz:
1 2 3 4
import java.util.*;
public class ExemploMatriz {
public static void lerMatriz(int m[][]) {
Scanner in = new Scanner(System.in);
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
System.out.print("m[" + i + "," + j + "] = ");
m[i][j] = in.nextInt();
} } }
public static void modificarMatriz(int n, int m[][]) {
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
m[i][j] = n * m[i][j];
} } }
ExemploMatriz.java
Note que o método
modificarMatriz(n,m)multiplica cada elemento de m pelo valor de n.
3. Vetores e Matrizes 3. Vetores e Matrizes
© ELFS 83
public static int[][] somarMatrizes(int a[][], int b[][]) {
int soma[][] = a;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
soma[i][j] = a[i][j] + b[i][j];
} }
return soma;
}
public static void mostrarMatriz(int m[][]) {
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
System.out.printf("%4d",m[i][j]);
}
System.out.println();
} }
public static void main (String [] args) {
int numLins,numCols,mat1[][];
Scanner in = new Scanner(System.in);
System.out.print("Número de linhas: ");
numLins = in.nextInt();
System.out.print("Número de colunas: ");
numCols = in.nextInt();
mat1 = new int[numLins][numCols];
lerMatriz(mat1);
System.out.println("\nMatriz 1:");
mostrarMatriz(mat1);
int mat2[][] = new int[numLins][numCols];
mat2 = (int[][])mat1.clone();
modificarMatriz(2,mat2);
System.out.println("\nMatriz 2:");
mostrarMatriz(mat2);
int mat3[][] = somarMatrizes(mat1,mat2);
System.out.println("\nMatriz 3:");
mostrarMatriz(mat3);
} }
Se mat1 for:
1 2 3 4 quais serão as matrizes mat2e mat3?
3. Vetores e Matrizes 3. Vetores e Matrizes
© ELFS 85
• Exercício. Construir uma classe que represente uma carta de baralho.
Construir um programa que simula a distribuição de um conjunto de cartas.
public class CartaBaralho {
private int face; // face da carta private int naipe; // naipe da carta public CartaBaralho(int nFace, int nNaipe) {
face = nFace;
naipe = nNaipe;
}
public String toString() { String faces[] =
{"Não usado","Ás","Dois","Trê̂̂̂s","Quatro","Cinco","Seis",
"Sete","Oito","Nove","Dez","Valete","Dama","Rei"};
String naipes[] =
{"Não usado","Ouros","Copas","Espadas","Paus"};
return faces[face] + " de " + naipes[naipe];
} }
CartaBaralho.java
Notar que a face da carta é um inteiro de 1 (ás) até 13 (rei). O naipe da carta é um inteiro de 1 a 4. O índice 0 não é usado.
import java.util.Random;
import javax.swing.JOptionPane;
public class DistribuicaoCartas {
public static void main(String[] args) {
String s;
CartaBaralho cb[];
boolean jaSaiu[][] = new boolean[14][5];
int nCartas, face, naipe;
Random r = new Random();
for (int i = 0; i < 14; i++) for (int j = 0; j < 5; j++)
jaSaiu[i][j] = false;
s = JOptionPane.showInputDialog("Quantas cartas?");
nCartas = Integer.parseInt(s);
cb = new CartaBaralho[nCartas];
3. Vetores e Matrizes 3. Vetores e Matrizes
DistribuicaoCartas.java
Notar que cbé um vetor de objetos da classe CartaBaralho. A matriz jaSaiuindica as cartas que já sairam.
© ELFS 87
// Gerar as cartas, aleatoriamente for (int i = 0; i < nCartas; i++) {
do {
face = r.nextInt(13)+1;
naipe = r.nextInt(4)+1;
}
while (jaSaiu[face][naipe]);
jaSaiu[face][naipe] = true;
cb[i] = new CartaBaralho(face,naipe);
}
// Mostrar as cartas geradas for (int i = 0; i < nCartas; i++) {
System.out.println("Carta " + (i+1) + ": " + cb[i].toString());
} } }
O método toString()já existe para todo objeto e efetua a conversão do objeto para um string. Para a classe CartaBaralho esse método foi redefinido.
Operações com Vetores
• Após um vetor ter sido criado não é possível redimensioná-lo. Se isto for necessário, deve-se criar um outro vetor da dimensão desejada e fazer o vetor antigo apontar para o novo.
• A classe System oferece um método especial: arraycopy(), que permite realizar cópias de vetores.
Exemplo:
// redimensionamento através de uma cópia int v1[] = {1, 2, 3, 4, 5};
v1[5] = 10 // Erro: índice fora dos limites int v2[] = new int[10];
System.arraycopy(v1, 0, v2, 0, v1.length);
v2[5] = 10; // Ok, os índices de v2 vão de 0 a 9
arraycopy(v1, i1, v2, i2, n) - Copia nelementos do vetor v1(a partir do elemento de índice igual a i1) para posições do vetor v2que iniciam em i2. Após a cópia, novos elementos podem ser definidos para o novo vetor.
3. Vetores e Matrizes 3. Vetores e Matrizes
© ELFS 89
• Outra forma de copiar um vetor é produzir um "clone" do vetor.
public class TestaClone1 {
public static void main(String[] args) { int a1[] = {1, 2, 3, 4};
int a2[] = (int[])a1.clone();
System.out.println((a1 == a2));
a1[1]++;
System.out.println(a1[1]);
System.out.println(a2[1]);
} }
TestaClone1.java
A saída será:
false 3 2
public class TestaClone2 {
public static void main(String[] args) { int m1[][] = {{1, 2}, {3, 4}};
int m2[][] = (int[][])m1.clone();
System.out.println((m1 == m2));
System.out.println(m1[0] == m2[0]);
m1[1][1]++;
System.out.println(m1[1][1] + " " + m2[1][1]);
} }
TestaClone2.java Note que os componentes de um vetor e de um clone
desse vetor são variáveis diferentes.
A saída será:
false true 5 5 Note que para matrizes, a clonagem ésuperficial, ou seja, cria
apenas uma nova referência. Os subvetores(linhas da matriz) são compartilhados.
• Em Java é possível criar métodos que recebem um número não especificado de parâmetros. Um tipo seguido por reticências (...) indica que o método recebe um número variável de parâmetros deste tipo. As reticências podem ocorrer apenas uma vez e devem ser
colocadas no fim da lista de parâmetros.
• No corpo do método, a lista de parâmetros de comprimento variável é tratada como um vetor.
Exemplo:
public class CalcularMedia {
public double media(double... valor) {
double soma = 0.0;
for (int i = 0; i < valor.length; i++) {
soma = soma + valor[i];
}
return (soma/valor.length);
} }
3. Vetores e Matrizes 3. Vetores e Matrizes
CalcularMedia.java
Notar que o parâmetro valor é tratado como um vetor no corpo do método.
© ELFS 91
import java.util.Locale;
public class TesteMedias {
public static void main(String[] args) {
double d1 = 10.0;
double d2 = 20.0;
double d3 = 30.0;
double d4 = 40.0;
CalcularMedia cm = new CalcularMedia();
System.out.printf(Locale.US,"Valores: %4.1f, %4.1f, %4.1f, %4.1f\n", d1,d2,d3,d4);
System.out.printf(Locale.US,"Média dos dois primeiros = %5.2f\n", cm.media(d1,d2));
System.out.printf(Locale.US,"Média dos trê̂̂̂s primeiros = %5.2f\n", cm.media(d1,d2,d3));
System.out.printf(Locale.US,"Média de todos os quatro = %5.2f\n", cm.media(d1,d2,d3,d4));
} }
TesteMedias.java
O método printf() pode ser usado com um primeiro parâmetro opcional, que indica como os valores de ponto flutuante devem ser exibidos: com vírgula ou com ponto.
O parâmetro Locale.US usado no método printf() indica que os valores devem ser formatados como nos USA, ou seja, usando ponto decimal. Sem este parâmetro será usado o formato conforme configurado no sistema operacional.
• Exercício. Construir um programa que simula o lançamento de dois dados. O programa deve usar um objeto da classe Random para lançar os dados. Como cada dado pode mostrar um valor de 1 a 6, a soma dos dois dados varia de 2 a 12. O programa deve lançar os dados 30000 vezes. Utilizar um vetor para guardar o número de vezes que cada possível valor da soma ocorreu. Mostrar o valor da soma mais frequente e o valor da soma menos frequente.
• Qual deverá ser a soma mais frequente?
• Qual deverá ser a soma menos frequente?
3. Vetores e Matrizes 3. Vetores e Matrizes