Capítulo 7 Vectores A importância dos vectores

Propaganda
Capítulo 7
Vectores
Vectores (array) uni-dimensionais e bi-dimensionais
Algoritmos básicos com vectores: contagem e pesquisa de elementos
Alteração de dimensão de vectores
Vectores dinâmicos (array list)
Classes wrapper, auto-boxing e o ciclo for generalizado
A importância dos vectores
• Como determinar quais as temperaturas da semana acima da média?
...
int count;
double temperature, sum, average;
Scanner keyboard = new Scanner(System.in);
System.out.println(“Enter the 7 temperatures of the week “);
for (int count = 0; count < 7; count++)
{
temperature = keyboard.nextDouble();
sum = sum + temperature
}
average = sum / 7;
...
Introdução à Programação
2007/08
A. Lopes
Vectores (arrays)
• Um vector é uma sequência de valores do mesmo tipo. Dito de outra
forma, é uma colecção de variáveis do mesmo tipo
• Construção e armazenamento de um vector
// vector armazenado numa variável do tipo double[]
double[] data = new double[10];
• Na criação de um vector, os seus elementos são inicializados com valores
de acordo com o respectivo tipo
• números: com o valor 0
• tipo boolean: com o valor false
• referências a objectos: com o valor null
Introdução à Programação
2007/08
A. Lopes
Vectores
• Acesso a um elemento
• utilização de [ ]
• o índice é um expressão cujo resultado é um número inteiro
data[2] = 29.95; // armazena um valor no vector
referência a um vector
e ao valor do elemento
Introdução à Programação
2007/08
A. Lopes
Vectores
• Utilização de um valor guardado no vector
System.out.println("The value of this data item is " + data[4]);
• A dimensão do vector pode ser consultada em data.length. Este atributo é
definido aquando da criação do vector e não é alterável
• Os índices variam de 0 a length - 1
• Acesso a um elemento não existente resulta num erro de limites do vector
double[] data = new double[10];
data[10] = 29.95; // incorrecto
• Os vectores têm comprimento fixo - a sua dimensão - o que pode ser
limitativo em alguns casos
Introdução à Programação
2007/08
A. Lopes
Construção de um vector
new typeName [ length ]
Exemplo:
new double[10]
Objectivo:
Construir um vector com determinada dimensão (ou comprimento)
Introdução à Programação
2007/08
A. Lopes
Acesso a um elemento de um vector
arrayReference [ index ]
Exemplo:
data[2]
Objectivo:
Aceder a um elemento do vector
Introdução à Programação
2007/08
A. Lopes
Vectores parcialmente preenchidos
• O comprimento de um
vector é o número máximo
de elementos no vector
• Geralmente, um vector
nunca está totalmente
preenchido. É pois
conveniente utilizar uma
variável em paralelo, que
guarde o número de
elementos efectivamente
definidos no vector
• Essa variável em paralelo
é actualizada sempre que
existam alterações no
número de elementos
efectivos no vector
Introdução à Programação
final int DATA_LENGTH = 100;
double[] data = new double[DATA_LENGTH];
int dataSize = 0;
data[dataSize] = x;
dataSize++;
2007/08
A. Lopes
Cópia de vectores
cópia da referência ao vector
• A cópia de uma variável do tipo array origina a existência de uma segunda
referência ao mesmo vector
double[] data = new double[10];
// preenche o vector
...
double[] prices = data;
duas variáveis para o mesmo vector
Introdução à Programação
2007/08
A. Lopes
Cópia de vectores
clonagem
• Utilização do método clone de modo a que a cópia seja totalmente efectiva
cast é
obrigatório
double[] prices = (double[]) data.clone();
Introdução à Programação
2007/08
A. Lopes
Cópia de vectores
cópia dos elementos de um vector
System.arraycopy(from, fromStart, to, toStart, count);
Introdução à Programação
2007/08
A. Lopes
Inserção de um elemento num vector
System.arraycopy(data, i, data, i + 1, data.length - i - 1);
data[i] = x;
o espaço a libertar,
para inserir x
Introdução à Programação
2007/08
A. Lopes
Remoção de um elemento de um vector
System.arraycopy(data, i + 1, data, i, data.length - i - 1);
o elemento a remover
Introdução à Programação
2007/08
A. Lopes
Crescimento de um vector
• Quando a capacidade do vector é atingida, e sendo necessário mais
espaço, o vector tem de crescer. Para isso:
• cria-se um novo vector, de maior dimensão (o dobro por exemplo)
double[] newData = new double[2 * data.length];
• copiam-se todos os elementos do vector em uso para esse novo vector
System.arraycopy(data, 0, newData, 0, data.length);
• armazena-se a referência desse novo vector na variável em causa
data = newData;
Introdução à Programação
2007/08
A. Lopes
Crescimento de um vector
1
double[] newData = new double[2 * data.length];
2
System.arraycopy(data, 0, newData, 0, data.length);
3
data = newData;
3
2
1
Introdução à Programação
2007/08
A. Lopes
Vectores e elementos de vectores em
métodos
• Uma variável indexada de um vector pode ser utilizada em qualquer parte
em que uma variável do mesmo tipo é utilizada. Por exemplo, como
argumento de um método
• A declaração de um vector num método é análoga à declaração normal de
um vector
• Um método pode retornar um vector
Introdução à Programação
2007/08
A. Lopes
Vectores e elementos de vectores em
métodos
import java.util.*;
public class vectorMetodosDemo {
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
}
public static int[] geraNumeros(int n) {
! int [] aleatorios = new int[n];
! Random gerador = new Random();
! for (int i=0; i<n; i++)
! ! aleatorios[i] = gerador.nextInt(n); // um numero em [0..n[
! return aleatorios;
}
public static void mostraNumeros(int[] vec) {
! for (int i=0; i< vec.length; i++)
! ! System.out.println("Numero " + i + ": " + vec[i]);
}!
public static void main(String[] args) {
! ! !
! Scanner in = new Scanner(System.in);
! System.out.println("Quantidade de numeros aleatorios a gerar: ");
! int n = in.nextInt();
! int [] numeros = geraNumeros(n);
! mostraNumeros(numeros);!
}
Introdução à Programação
2007/08
A. Lopes
Vectores de objectos em vez de vectores
paralelos
// evitar vectores paralelos
int[] accountNumbers;
double[] balances;
Introdução à Programação
2007/08
A. Lopes
Vectores de objectos em vez de vectores
paralelos
• Os vectores paralelos devem dar lugar a vectores de objectos de
determinada classe, e os seus métodos passam a ser aplicados aos
elementos do vector
BankAccount[] accounts = new BankAccount(10);
...
System.out.println(“Saldo da conta: “ + accounts[0].getBalance());
Introdução à Programação
2007/08
A. Lopes
Exemplo de utilização de vectores
um banco com contas bancárias
1
Bank
Bank
- accounts : BankAccount[]
- accountsCounter : int
+ Bank( limit : int )
+ addAccount( acc : BankAccount)
+ removeAccount( indAccount : int )
+ getTotalBalance() : double
+ accountsAtLeast( atLeast : double ) : int
+ getMaximum() : BankAccount
+ find( accountNumber : int ) : BankAccount
+ accountAt( indAccount : int ) : BankAccount
+ getNumberAccounts() : int
+ getLimitAccounts() : int
Introdução à Programação
2007/08
*
BankAccount
BankAccount
- balance : double
- accountNumber : int
+ BankAccount( number : int )
+ BankAccount( number : int, initialBalance : int )
+ deposit( amount : int )
+ withdraw( amount : int )
+ getBalance() : double
+ getAccountNumber() : int
A. Lopes
Algoritmos básicos com vectores
pesquisar um valor
• Analisa todos os elementos até encontrar o/um que procura
/**
Finds a bank account with a given number.
@param accountNumber the number to find
accounts
@return the account with the given number, or null if there
is no such account
*/
1001
123.40
public BankAccount find(int accountNumber)
{
1002
34.50
for (int i = 0; i < accountsCounter; i++)
1007
1993.0
{
if (accounts[i].getAccountNumber() == accountNumber)
1003
57.80
// found an element
return accounts[i];
1005
1123.20
}
return null; // no element has been found
1006
1678.30
}
Introdução à Programação
2007/08
A. Lopes
Algoritmos básicos com vectores
contagem de determinado elemento
• Analisa todos os elementos e conta os que têm determinada característica
que procura até chegar ao fim do vector
/**
Counts the number of bank accounts whose balance is at least a
given value.
@param atLeast the balance required to count an account
@return the number of accounts having at least the given balance
*/
accounts
1001
123.40
1002
34.50
public int accountsAtLeast(double atLeast)
{
int matches = 0;
for (int i = 0; i < accountsCounter; i++)
{
if (accounts[i].getBalance() >= atLeast)
matches++; // found an element
}
return matches;
1003
57.80
1005
1123.20
1006
1678.30
}
Introdução à Programação
1007
1993.0
2007/08
A. Lopes
Algoritmos básicos com vectores
pesquisa o máximo e o mínimo
• Inicializa o potencial candidato com um elemento inicial. De seguida,
percorrendo o vector, compara o candidato com os restantes elementos,
actualizando-o se encontrar um elemento de maior (menor) valor
• O método só funciona se existir pelo menos um elemento no
vector. Se o vector estiver vazio, deve devolver null
/**
Gets the bank account with the largest balance.
@return the account with the largest balance, or null if the bank
has no open accounts
*/
public BankAccount getMaximum()
{
if (accountsCounter == 0) return null;
BankAccount largestYet = accounts[0];
for (int i = 1; i < accountsCounter; i++)
{
BankAccount acc = accounts[i];
if (acc.getBalance() > largestYet.getBalance())
largestYet = acc;
}
return largestYet;
}
Introdução à Programação
2007/08
accounts
1001
123.40
1002
34.50
1007
1993.0
1003
57.80
1005
1123.20
1006
1678.30
A. Lopes
Algoritmos básicos com vectores
remove um elemento
/**
Removes an account located at the specified indice in the bank,
and moves the last account to that position.
@param indAccount is the indice in the bank of the account to be
removed
@return the removed account or null if the operation is not valid
*/
public BankAccount removeAccount(int indAccount)
{
accounts
1001
123.40
if (indAccount >= 0 && indAccount < accountsCounter)
{
1002
34.50
BankAccount acc = accounts[indAccount];
accountsCounter--;
1007
1993.0
accounts[indAccount] = accounts[accountsCounter];
1003
57.80
// the last one has just been moved to this position
return acc;
}
return null;
1006
1678.30
}
Introdução à Programação
1005
1123.20
2007/08
A. Lopes
Ficheiro Bank.java
Introdução à Programação
2007/08
A. Lopes
Ficheiro BankAccount.java
Introdução à Programação
2007/08
A. Lopes
Ficheiro BankTester.java
Introdução à Programação
2007/08
A. Lopes
Vectores bi-dimensionais
• Para construir um vector bi-dimensional, é preciso indicar o número de
linhas e de colunas que se pretende
• Os elementos do vector são acedidos através de um índice duplo a[i][j]
final int ROWS = 3;
final int COLUMNS = 3;
String[][] board = new String[ROWS][COLUMNS];
board[i][j] = "x";
Introdução à Programação
2007/08
A. Lopes
Percurso em vectores bi-dimensionais
• Por norma, utilizam-se dois ciclos for encadeados quando se pretende
preencher ou pesquisar o vector
for (int i = 0; i < ROWS; i++)
for (int j = 0; j < COLUMNS; j++)
board[i][j] = " ";
Introdução à Programação
2007/08
A. Lopes
Vectores bi-dimensionais de dimensão
diferenciada
• O Java permite a existência de vectores cujo comprimento das linhas
difere entre si
int[][] vec = new int[3][];
// vector com 3 linhas
vec[0] = new int[4];
// 1ª linha terá 4 inteiros
vec[1] = new int[5];
// 2ª linha terá 5 inteiros
vec[2] = new int[2];
// 3ª linha terá 2 inteiros
vec[0][0] = 34;
...
for (int i=0; i < vec.length; i++)
for (int j=0; j < vec[i].length; j++)
System.out.println(“vec[“+i+”][“+j+”] : “+vec[i][j]);
// exemplo, em alternativa, de inicialização na declaração
int[][] vec = { {34, 2, 5, 6}, {1, 2, 3, 4, 5}, {2, 1} };
Introdução à Programação
2007/08
A. Lopes
Ficheiro TicTacToe.java
Introdução à Programação
2007/08
A. Lopes
Ficheiro TicTacToeTester.java
Introdução à Programação
2007/08
A. Lopes
Vectores dinâmicos (array list)
• A classe ArrayList permite manipular uma sequência de objectos, que pode
aumentar ou diminuir se necessário
• São disponibilizados vários métodos para tarefas comuns, como por
exemplo para inserir ou remover elementos. O método size indica o
número de elementos
• A classe ArrayList é uma classe genérica: ArrayList<T> “colecciona”
objectos do tipo T
ArrayList<BankAccount> accounts = new ArrayList<BankAccount>();
accounts.add(new BankAccount(1001));
accounts.add(new BankAccount(1015));
accounts.add(new BankAccount(1022));
Introdução à Programação
2007/08
A. Lopes
Acesso a elementos de um vector dinâmico
• os índices começam em 0 e não pode se pode aceder a nenhum elemento
fora dos respectivos limites
// obtém o 3º elemento do vector
BankAccount anAccount = accounts.get(2);
int i = accounts.size();
anAccount = accounts.get(i);
// erro: os índices têm de estar entre 0 e i-1
Introdução à Programação
2007/08
A. Lopes
Inserção de elementos
• escrever sobre um valor existente
BankAccount anAccount = new BankAccount(1729);
accounts.set(2, anAccount);
• inserir um valor antes do valor que está num índice
1
2
accounts.add(i, a)
• para acrescentar
accounts.add(a)
Introdução à Programação
2007/08
A. Lopes
Remoção de elementos
• remover um elemento num índice
1
2
accounts.remove(i)
• remover todos os elementos
accounts.clear()
Introdução à Programação
2007/08
A. Lopes
Ficheiro ArrayListTester.java
... com a classe BankAccount
Introdução à Programação
2007/08
A. Lopes
Wrappers
• Não é possível colocar tipos primitivos directamente em vectores
dinâmicos. Para processar valores desse tipo, é necessário utilizar classes
wrapper
ArrayList<Double> data = new ArrayList<Double>();
data.add(29.95);
double x = data.get(0);
Objecto de uma classe Wrapper
Introdução à Programação
2007/08
A. Lopes
Wrappers existentes
Introdução à Programação
2007/08
A. Lopes
Auto-boxing
• Com auto-boxing (Java 5.0), a conversão entre um tipo primitivo e a
correspondente classe wrapper é automática
• Auto-boxing também funciona em expressões aritméticas
Double d = 29.95; // auto-boxing;
// equivalente a Double d = new Double(29.95);
double x = d;
// auto-unboxing;
// equivalente a double x = d.doubleValue();
1. auto-unbox d num double
Double e = d + 1;
2. adiciona 1
3. auto-box o resultado num novo
Double
Introdução à Programação
2007/08
4. armazena a referência no recém criado
objecto wrapper em e A. Lopes
Ciclo for generalizado
• Percorre todos os elementos da colecção, não permitindo alterações nas
referências a esses elementos (ou nos próprios se forem do tipo primitivo)
double[] data = ...;
double sum = 0;
for (double e : data) // "para cada e em data"
{
sum += e;
}
• Alternativa clássica:
double[] data = ...;
double sum = 0;
for (int i = 0; i < data.length; i++)
{
double e = data[i];
sum += e;
}
Introdução à Programação
2007/08
A. Lopes
Ciclo for generalizado
• Com vectores dinâmicos
ArrayList<BankAccount> accounts = ... ;
double sum = 0;
for (BankAccount a : accounts)
{
sum += a.getBalance();
}
• equivalente ao ciclo clássico:
double sum = 0;
for (int i = 0; i < accounts.size(); i++)
{
BankAccount a = accounts.get(i);
sum += a.getBalance();
}
Introdução à Programação
2007/08
A. Lopes
Ciclo "for each"
for (type variable : collection)
statement
Exemplo:
for (double e : data)
sum += e;
Objectivo:
Para executar um ciclo para cada elemento da colecção. Em cada iteração, a
variável e é associada ao próximo elemento da colecção. De seguida, executa
a instrução.
Note-se que, dentro do ciclo, não é possível alterar a variável e
Introdução à Programação
2007/08
A. Lopes
Download