Arreglos en Java

Declaración y acceso

Un arreglo (array) es una colección ordenada de elementos del mismo tipo, que son accesibles a través de un índice.
Un arreglo puede contener datos primitivos o referencias a objetos.
Los arrays se deben declarar:
[modificadores] tipo_variable[ ] nombre;
Por ejemplo:
int [ ] a;
Punto [ ] p;
La declaración dice que a es un array de enteros y p un array de objetos de tipo Punto. De manera más precisa a es una referencia a una colección de enteros, aunque todavía no se sabe cuantos elementos tiene el array. p es una referencia a una colección de referencias que apuntarán objetos Punto.

Un array se crea como si se tratara de un objeto (de hecho las variables de tipo array son referencias):
a = new int [5];
p = new Punto[3];
En el momento de la creación del arreglo se dimensiona el mismo y se reserva la memoria necesaria.

También puede crearse de forma explícita asignando valores a todos los elementos del array en el momento de la declaración, de la siguiente forma:
int [ ] a = { 2 , 3 , 5 };
El acceso a los elementos del array se realiza indicando entre corchetes el elemento del array que se desea, teniendo en cuenta que siempre el primer elemento del array es el índice 0. Por ejemplo a[1]. En este ejemplo los índices del array de tres elementos son 0, 1 y 2. Si se intenta usar un índice que está fuera del rango válido para ese arreglo se produce un error (en realidad una excepción. Las excepciones serán tratadas en un capítulo posterior) de 'Indice fuera de rango'. En el ejemplo anterior se produce esta excepción si el índice es menor que 0 o mayor que 2.

Se puede conocer el número de elementos de un array usando la variable length. En el ejemplo a.length contiene el valor 3.

Un arreglo, como cualquier otra referencia puede formar parte de la lista de parámetros o constituir el valor de retorno de un método. En ambos casos se indica que se trata de un array con los corchetes que siguen al tipo. Por ejemplo:
String [ ] metodoConArrays ( Punto [ ] ) { . . }
El método metodoConArrays recibe como parámetro un array de Puntos y devuelve un array de Strings. El método podría invocarse de la siguiente forma:
Punto p [ ] = new Punto [3];
. . .
String [ ] resultado = metodoConArrays(p);

Arreglos multidimensionales

Es posible declarar arrays de más de una dimensión. Los conceptos son los mismos que para los arreglos monodimensionales.

Por ejemplo:
int [ ][ ] a = { { 1 , 2 } , { 3 , 4 } , { 5 , 6 } };
int x = a [1][0];   // contiene 3
int y = a [2][1];   // contiene 6
Se pueden recorrer los elementos de un array multidimensional, de la siguiente forma:
int [ ][ ] a = new int  [3][2];
for ( int i = 0 ; i < a.length ; i++ ) {
    for ( int j = 0 ; j < a[i].length ; j++) {
        a[i][j] = i * j;
    }
}
Obsérvese en el ejemplo la forma de acceder al tamaño de cada dimensión del array.

REFERENCIAS:       arrakis

Control de la ejecución

Resumen de operadores

La siguiente tabla muestra un resumen de los operadores clasificados por grupos:

Grupo de operador Operador Significado
Aritméticos +
-
*
/
%
Suma
Resta
Multiplicación
División
Resto
Relacionales >
>=
<
<=
==
!=
Mayor
Mayor o igual
Menor
Menor igual
Igual
Distinto
Lógicos &&
||
!
AND
OR
NOT
A nivel de bits &
|
^
<<
>>
>>>
AND
OR
NOT
Desplazamiento a la izquierda
Desplazamiento a la derecha rellenando con 1
Desplazamiento a la derecha rellenando con 0
Otros +
++
--
=
+=
-=
*=
/=
?:
Concatenación de cadenas
Autoincremento (actua como prefijo o sufijo)
Autodecremento (actua como prefijo o sufijo)
Asignación
Suma y asignación
Resta y asignación
Multiplicación y asignación
División y asignación
Condicional

Ejecución condicional

El formato general es:
if (expresion_booleana)
    sentencia
[else
    sentencia]
sentencia (a todo lo largo de este capítulo) puede ser una sola sentencia o un bloque de sentencias separadas por ; y enmarcadas por llaves { y }. Es decir
if (expresion_booleana) {
    sentencia;
    sentencia;
    . . .
}
else {
    sentencia;
    sentencia;
    . . .
}
expresion_booleana es una expresión que se evalua como true o false (es decir, de tipo booleano). Si el resultado es true la ejecución bifurca a la sentencia que sigue al if . En caso contrario se bifurca a la sentencia que sigue al else.

Los corchetes en el formato anterior indican que la clausula else es opcional.

Iteraciones con while

Sintaxis formato 1:
while (expresion_booleana)
    sentencia
Sintaxis formato 2:
do
    sentencia
while (expresion_booleana)
La sentencia o bloque se sentencias (se aplica la misma idea que para el if-else) se ejecuta mientras que la expresion_booleana se evalue como true.

La diferencia entre ambos formatos es que en el primero la expresión se evalua al principio del bloque de sentencias y en el segundo se evalua al final.

Iteraciones con for

El formato es:
for ( inicializacion ; expresion_booleana ; step )
    sentencia
inicializacion es una sentencia que se ejecuta la primera vez que se entra en el bucle for. Normalmente es una asignación, es opcional.

expresion_booleana es una expresión que se evalua antes de la ejecución de la sentencia, o bloque de sentencias, para cada iteración. La sentencia o bloque de sentencias se ejecutan mientras que la expresion_booleana se evalue como cierta. Es opcional.

step es una sentencia que se ejecuta cada vez que se llega al final de la sentencia o bloque de sentencias. Es opcional.

Una utilización clásica de un bucle de tipo for se muestra a continuación para evaluar un contador un número fijo de veces:
for ( int i = 1 ; i <= 10 ; i++ )
    sentencia
La sentencia (o bloque de sentencias) se evaluará 10 veces. En cada ejecución (pasada) el valor de la variable i irá variando desde 1 hasta 10 (inclusive). Cuando salga del bloque de sentencias i estará fuera de su ámbito (porque se define en el bloque for).

Si se omiten las tres clausulas del bucle se obtiene un bucle infinito:
for ( ; ; )
    sentencia
Obsérvese que se pueden omitir las clausulas pero no los separadores (;).

Evaluación múltiple

El formato es:
switch ( expresion_entera ) {
    case valor_entero:
        sentencia;
    break;
    case valor_entero:
        sentencia;
    break;
    . . .
    default:
    sentencia;
}
Cuidado: en el switch la expresión que se evalua no es una expresión booleana como en el if-else, sino una expresión entera.

Se ejecuta el bloque case cuyo valor coincida con el resultado de la expresión entera de la clausula switch. Se ejecuta hasta que se encuentra una sentencia break o se llega al final del switch.

Si ningún valor de case coincide con el resultado de la expresión entera se ejecuta el bloque default (si está presente).

default y break son opcionales.

Devolución de control

El formato es:
return valor
Se utiliza en los métodos para terminar la ejecución y devolver un valor a quien lo llamó.

valor debe ser del tipo declarado en el método.

valor es opcional. No debe existir cuando el método se declara de tipo void. En este caso, la claúsula return al final del método es opcional, pero puede usarse para devolver el control al llamador en cualquier momento.

Expresiones

La mayor parte del trabajo en un programa se hace mediante la evaluación de expresiones, bien por sus efectos tales como asignaciones a variables, bien por sus valores, que pueden ser usados como argumentos u operandos en expresiones mayores, o afectar a la secuencia de ejecución de instrucciones.

Cuando se evalua una expresión en un programa el resultado puede denotar una de tres cosas:
  • Una variable. (Si por ejemplo es una asignación)
  • Un valor. (Por ejemplo una expresión aritmética, booleana, una llamada a un método, etc.)
  • Nada. (Por ejemplo una llamada a un método declarado void)
Si la expresión denota una variable o un valor, entonces la expresión tiene siempre un tipo conocido en el momento de la compilación. Las reglas para determinar el tipo de la expresión varían dependiendo de la forma de las expresiones pero resultan bastante naturales. Por ejemplo, en una expresión aritmética con operandos de diversas precisiones el resultado es de un tipo tal que no se produzca pérdida de información, realizandose internamente las conversiones necesarias. El análisis pormenorizado de las conversiones de tipos, evaluaciones de expresiones, etc, queda fuera del ámbito de estos apuntes. En general puede decirse que es bastante similar a otros lenguajes, en particular C, teniendo en cuenta la característica primordial de Java de tratarse de un lenguaje con control fuerte de tipos.

REFERENCIAS:       arrakis