Ir para o conteúdo

Tabelas (Arrays, Vectores)

Antes de iniciarmos o tema, vamos tentar definir um termo a usar que possa ser uniforme em todo o tutorial. Array pode ser traduzido para vector, sendo esta uma tradução comum, ou para matriz quando falamos em duas dimensões (linhas e colunas) ou, neste caso, para tabelas. A tradução ou termo a usar não é consensual, e piora com o tema que pretendemos introduzir.

Desta forma, iremos usar o termo original, array, quando nos referirmos a um array de dimensão 1 1, e array de arrays quando nos referirmos a uma array de dimensão maior que 1, por exemplo, uma matriz.

A razão pela qual não iremos usar o termo matriz, é porque em Java, um array multidimensional, ou neste caso de duas dimensões, não tem de ter todas as linhas do mesmo tamanho ao contrário de outras linguagens. Por exemplo, em C, ao declarar a variável int m[2][3], estaremos a declarar um array com duas linhas e cada linha tem 3 colunas, C não nos permite fazer, int m[2][] dado que na declaração, o tamanho total do array tem de ser conhecido. Na verdade é possível ter arrays com linhas de tamanhos variáveis em C. O que se pretende salientar é a diferença na forma como são obtidos dado que para fazer o mesmo que em Java, teremos de usar memória dinâmica e a declaração das variáveis torna-se diferente, bem como o modo de acesso.

Portanto, a nível de declaração de arrays de tamanhos variáveis, C e outras linguagens, fazem uso de funções/mecanismos extra, enquanto que em Java os arrays são tratados como objectos e isso reflecte-se na forma como são declarados e usados.

Arrays como Objectos

Os arrays de Java são objectos e tal como uma String, ou qualquer outro objecto que seja por nós criado, os arrays em Java precisam ser instanciados recorrendo à palavra reservada new. E porque são objectos, podem ser facilmente passadas como parâmetros de métodos, ser feita a atribuição directa entre dois arrays ou serem devolvidas por métodos. No fundo, o que é passado, como em qualquer outro objecto, é uma referência e não uma cópia dos elementos.

A declaração de arrays é similar ao que é usado noutras linguagens:

//Para uma dimensão
TipoDeDados[] nomeDaVariavel;
//ou
TipoDeDados nomeDaVariavel[];

//Para várias dimensões
TipoDeDados[][] nomeDaVariavel;
//ou
TipoDeDados nomeDaVariavel[][];

TipoDeDados[][][] nomeDaVariavel;
//ou
TipoDeDados nomeDaVariavel[][][];

Mas, contrariamente a outras linguagens ao declararmos o array como indicado acima não conseguimos usá-lo para guardar dados sem antes reservarmos memória para os valores através de instanciação:

TipoDeDados[] nomeDaVariavel;

//Instanciar o array para 5 posições
nomeDaVariavel = new TipoDeDados[5];

//Instanciar e atribuir valor no mesmo passo
nomeDaVariavel = new TipoDeDados{valor1, valor2, valor3, ...};

//Declaração com instanciação e atribução, array de array
String[][] nomes = new String{{"maria", "joao", "paulo"}, {"andré", "carlos", "costa"}, ...}

Este processo de instanciação apenas nos oferece metade da solução. Já vimos as diferenças entre dados primitivos e objectos, sabemos que os dados primitivos não precisam ser instanciados e que os objectos precisam ser instanciados para que possamos usar as variáveis que para eles referenciam.

No caso de arrays, se o array é composto apenas por dados primitivos, a instanciação do array resulta numa variável que podemos usar imediatamente, mas se estivermos a trabalhar com arrays de objectos, então a instanciação do array apenas nos dá um array com todas as posições a null. Isto significa que, antes de podermos aceder a uma posição do array, precisamos instanciar o objecto que vai ficar guardado nessa posição.

Esta questão é particularmente importante quando pensamos em arrays de arrays dado que nos permite fazer instanciações parciais, por exemplo, numa matriz de 5x5 podemos instanciar apenas o primeiro array, correspondente às linhas, e mais tarde o segundo, correspondente a 5 colunas. Se trabalharmos com arrays que contenham arrays variáveis, em que cada linha tem diferentes números de colunas, esta característica é muito importante.

Utilitários

Para a manipulação de arrays, o Java oferece-nos a classe Arrays e o método System.arraycopy.

Com a classe temos à nossa disposição métodos de ordenação e de pesquisa que podemos usar para trabalhar os nossos arrays de forma facilitada. Com o arraycopy podemos fazer cópias rápidas dos valores dos nossos arrays, no entanto é necessário salvaguardar que o método arraycopy apenas efectua uma shallow copy, copiando apenas as referências. O resultado desta cópia é que ficamos com dois arrays, a cópia e o original, a apontar para os mesmos objectos.


  1. Não confundir com um array de uma posição, um array de dimensão 1 tem apenas uma linha.