You are on page 1of 17

Arreglos

H. Tejeda

Marzo 2016

Indice

1. Declaracion de arreglos 2

2. Inicializacion de arreglos 4

3. Uso de subndices variables en un arreglo 5

4. Declaracion y uso de arreglos de objetos 8

5. Busqueda y uso de arreglos paralelos 10

6. Paso y devolucion de arreglos en metodos 14

Para guardar un valor y usarlo se han usado variables. Se han usado ciclos que permiten reciclar
variables para ser usadas varias veces; ya que despues de haber creado una variable, asignarle un
valor, usar el valor, y luego, en iteraciones sucesivas en el ciclo, se reusa la variable con valores
diferentes.

En ocasiones se tienen situaciones en las cuales guardar un solo valor a la vez en memoria no es
suficiente. Por ejemplo, un supervisor de ventas que vigila 20 empleados podra querer determinar
si cada empleado ha hecho ventas por encima o por debajo del promedio. Con el valor de las ventas
del primer empleado ingresado en una aplicacion, no se puede determinar si esta por encima o por
debajo porque todava no se sabe el promedio hasta que se tengan los 20 valores. Desafortunada-
mente, s se intente asignar 20 valores de venta a la misma variable, cuando se asigne el valor para
el segundo empleado, este reemplaza el valor del primer empleado.

Una solucion posible es crear 20 variables de ventas de empleados separadas, cada una con un
nombre unico, para poder guardar todas las ventas hasta que se pueda calcular el promedio. Una
desventaja es que se ocupan 20 nombres de variables diferentes para asignar los valores y 20 sen-
tencias de asignacion diferentes. Para los nombres de las 20 variables diferentes la sentencia que
calcula el total de la venta sera compleja, quedando como:

total = primeraCant + segundaCant + terceraCant + ...

1
La sentencia anterior trabajara para 20 vendedores, pero que sucedera si se tienen 5,000 vende-
dores?

1. Declaracion de arreglos

La mejor solucion al problema de los 5,000 vendedores es creando un arreglo. Un arreglo es una
lista de datos con nombre teniendo todos ellos el mismo tipo. Cada dato es un elemento del
arreglo. Se declara una variable arreglo de la misma forma como se declara una variable simple,
pero se inserta un par de corchetes despues del tipo. Por ejemplo, para declarar un arreglo de
valores double para guardar las ventas, se puede escribir lo siguiente:

double [] ventas;

Nota. Se puede declarar una variable arreglo en Java poniendo los corchetes despues del nombre
del arreglo, como en double ventas[];. Este formato es empleado en C y C++, pero el formato
preferido entre los programadores de Java es poniendo los corchetes despues del tipo de la variable
y antes del nombre de la variable.

Se puede dar cualquier identificador legal que se quiera para un arreglo, pero los programadores de
Java nombran los arreglos siguiendo las mismas reglas usadas para variables, el nombre inicia con
minuscula y letras mayusculas iniciando palabras subsecuentes. Adicionalmente, varios programa-
dores observan una de las siguientes convenciones para hacer mas enfasis que el nombre representa
un grupo de datos:

Los arreglos son nombrados frecuentemente usando un sujeto plural como ventas.

Los arreglos son nombrados frecuentemente agregando una palabra final que implique un
grupo, como listaVentas, tablaVentas, o arregloVentas.

Despues de crear una variable arreglo, se necesita reservar espacio de memoria. Se usa el mismo
procedimiento para crear un arreglo que el empleado para crear un objeto.

Para declarar un arreglo y reservar memoria para este se hace en dos procesos distintos. Para
reservar localidades de memoria para 20 valores de ventas, se declara la variable arreglo y luego se
crea el arreglo mediante dos sentencias como sigue:

double [] ventas;
ventas = new double [20];

Al igual que con los objetos, se puede declarar y crear un arreglo en una sola sentencia con lo
siguiente:

double [] ventas = new double [20];

2
Con la sentencia anterior se reservan 20 localidades de memoria para 20 valores double. Se puede
distinguir cada dato ventas de los otros con un subndice. Un subndice es un entero contenido
dentro de corchetes que especifica uno de los elementos del arreglo. Cualquier arreglo de elementos
en Java esta numerado iniciando con cero, as que se pueden usar correctamente subndices de 0
hasta 19 al trabajar con un arreglo de 20 elementos. Es decir, el primer elemento del arreglo ventas
es ventas[0] y el ultimo elemento es ventas[19].

En otros lenguajes de programacion el primer elemento del arreglo es el elemento uno, lo cual es un
error comun al olvidar que en Java el primer elemento en un arreglo es el elemento cero. Tambien
lo anterior hace que se olvide que el subndice del ultimo elemento es uno menos que el tamano del
arreglo y no el tamano de este. Para no olvidar el uso correcto se puede pensar que el subndice
de un elemento indica la cantidad de elementos que le preceden. Si se emplea un subndice que es
negativo, o igual a, o mayor que el tamano del arreglo, el subndice esta fuera de lmites y un
mensaje de error es generado.

Cuando se trabaja con algun elemento del arreglo, se emplea de igual forma como se hace con una
variable. Por ejemplo, para asignar un valor al primer elemento de ventas en un arreglo, se usa
una sentencia de asignacion simple, tal como la siguiente:

ventas[0] = 12345.0;

Para mostrar el ultimo elemento del arreglo ventas de tamano 20, se escribe:

System.out.println(ventas[19]);

Cuando se declara o accesa un arreglo, se puede usar cualquier expresion para indicar el tamano,
siempre y cuando esta de un entero. Para declarar un arreglo double llamado valoresMoneda, se
podra usar cualquiera de las siguientes:

Una constante literal entera


double [] valoresMoneda = new double [10];
Una constante con nombre entera
double [] valoresMoneda = new double [CANT ELEMS];
Una variable entera
double [] valoresMoneda = new double [cantElems];
Un calculo que involucre variables con enteros, o de un entero
double [] valoresMoneda = new double [x + y * z];
Un valor entero devuelto por un metodo
double [] valoresMoneda = new double [getElementos()];

Actividad 1. Escribir una aplicacion que declare y cree un arreglo para guardar al menos cinco
valores double. Que asigne a cada uno de los elementos del arreglo un valor arbitrario y que muestre
en pantalla las asignaciones hechas.

3
2. Inicializacion de arreglos

Una variable que tiene un tipo primitivo, como un int, guarda un valor. Una variable con un tipo
referencia, como un arreglo, guarda una direccion de memoria donde un valor esta guardado. Los
nombres de arreglos contienen referencias, al igual como todos los objetos Java.

No se asigna direccion de memoria cuando se declara un arreglo usando solo un tipo de dato,
corchetes, y un nombre. El nombre de la variable arreglo tiene el valor especial null, que significa
que el identificador no esta asociado con alguna direccion, como sucede con el valor de numeros
que es null en la siguiente declaracion:

int [] numeros;

Al emplear la palabra reservada new para definir un arreglo, el nombre arreglo recibe el valor de
una direccion de memoria, como se hace en la siguiente sentencia al definir numeros

int [] numeros = new int [10];

En esta declaracion numeros tiene una direccion, pero cada elemento de numeros tiene el valor de
cero porque es un arreglo de enteros. Los elementos en un arreglo float o double tienen asignado
0.0. Por defecto, los elementos de un arreglo char tienen asignado \u0000, el cual es el valor
Unicode para el caracter null, y los elementos de un arreglo boolean tienen asignado false. En
arreglos de objetos, incluyendo String, cada elemento tiene asignado null por defecto.

Ademas de asignar un valor a un elemento de un arreglo, como en:

numeros[0] = 45;

Se pueden tambien asignar valores diferentes al valor por defecto a los elementos de un arreglo en
la creacion. Para inicializar un arreglo, se usa una lista de inicializacion de valores separados por
comas y encerrados entre llaves. Dando valores para todos los elementos en un arreglo tambien es
llamado poblar un arreglo.

Por ejemplo, si se quiere crear un arreglo llamado multiplosDiez y guardar los primeros seis
multiplos de diez en el arreglo, se puede declarar como sigue:

int[] multiplosDiez = {10, 20, 30, 40, 50, 60};

Observar el punto y coma al final de la sentencia.

Cuando se pueble un arreglo en la creacion dando una lista de inicializacion, no se da el tamano


del arreglo, el tamano es asignado de acuerdo a la cantidad de valores que se pongan en la lista
de inicializacion. Por ejemplo, el arreglo multiplosDiez definido previamente tiene tamano seis.
Tambien, cuando se inicializa un arreglo, no se requiere usar la palabra reservada new, la nueva
memoria es asignada de acuerdo al tamano de la lista dada.

4
No se puede directamente inicializar una parte de un arreglo en Java. En caso de que se requiera se
debera hacer individualmente, una vez que se haya creado el arreglo usando la palabra reservada
new.

Actividad 2. Modificar la actividad 1 para declarar, crear, e inicializar el arreglo usando una lista
de inicializacion.

3. Uso de subndices variables en un arreglo

Si se trata cada elemento de un arreglo como una entidad individual, no hay ventaja en declarar un
arreglo respecto a variables individuales de tipos primitivos. El poder de los arreglos se da cuando
se usan subndices que son variables, en vez de subndices que sean valores constantes.

Suponer que se declara un arreglo de cinco enteros para manejar igual cantidad de puntuaciones,
como se muestra enseguida:

int [] arregloPunt = {13, 23, 54, 79, 95};

Luego se quiere realizar la misma operacion con cada elemento del arreglo, tal como incrementar
cada puntuacion por una cantidad constante. Para incrementar cada elemento de arregloPunt por
tres puntos, por ejemplo, se puede escribir lo siguiente:

final int INCREMENTO = 3;


arregloPunt[0] += INCREMENTO;
arregloPunt[1] += INCREMENTO;
arregloPunt[2] += INCREMENTO;
arregloPunt[3] += INCREMENTO;
arregloPunt[4] += INCREMENTO;

Con un arreglo pequeno, la tarea es manejable, requiriendo solo cinco sentencias. Sin embargo, se
puede reducir la cantidad de codigo necesario usando una variable como subndice. Entonces, se
puede usar un ciclo para realizar la aritmetica con cada elemento, como en el siguiente ejemplo:

final int INCREMENTO = 3;


for (int sub = 0; sub < 5; ++sub)
arregloPunt[sub] += INCREMENTO;

La variable sub es puesta a cero, y entonces es comparado a cinco. Como el valor de sub es
menor que cinco, el ciclo se ejecuta y tres es agregado a arregloPunt[0]. Luego, la variable
sub es incrementada y se hace uno, que sigue siendo menor que cinco, as que el ciclo se ejecuta
nuevamente, arregloPunt[1] es incrementado por tres, y as sucesivamente. Un proceso que toma
cinco sentencias ahora toma solamente una. Considerar lo que sucedera si el arreglo hubiese tenido
100 elementos, habra requerido 95 sentencias adicionales, pero el unico cambio requerido, usando
el segundo metodo, es el cambio del tamano del arreglo a 100 en la segunda parte del ciclo for.

5
Cuando una aplicacion contiene un arreglo y se quiere usar cada elemento del arreglo en alguna
tarea, se sugiere usar ciclos que varen la variable de control del ciclo desde cero hasta uno menos
que el tamano del arreglo. Estas tareas pueden ser el alterar cada valor en el arreglo, sumar todos
los valores en el arreglo, o mostrar cada elemento en el arreglo. En una aplicacion que incluya
un arreglo es conveniente declarar una constante simbolica igual al tamano del arreglo y usar la
constante simbolica como un valor limitante en cada ciclo que procese el arreglo. De esta forma,
si el tamano del arreglo cambia mas adelante, solo se necesita modificar el valor guardado en la
constante simbolica, para no tener que buscar y modificar el valor limitante en cada ciclo que
procesa el arreglo. Un ejemplo sera como el siguiente:

int [] arregloPunt = {13, 23, 54, 79, 95};


final int INCREMENTO = 5;
final int CANT DE PUNT = 5;
for (int sub = 0; sub < CANT DE PUNT; ++sub)
arregloPunt[sub] += INCREMENTO;

Este formato tiene dos ventajas, primero, el uso de la constante simbolica, CANT DE PUNT, el lector
entiende que se esta procesando cada elemento del arreglo por el tamano del arreglo entero. Segundo,
si el tamano del arreglo cambia porque se agregaron o quitaron puntuaciones, solo se ocupa cambiar
el valor de la constante simbolica una sola vez.

Una segunda opcion, es usar un campo, variable de instancia, al que es asignado automaticamente
un valor para cada arreglo que es creado; el campo length contiene la cantidad de elementos en el
arreglo. El siguiente ejemplo repite el codigo previo mostrando como se usa este campo como valor
limitante en la parte central del ciclo for.

int [] arregloPunt = {13, 23, 54, 79, 95};


final int INCREMENTO = 3;
for (int sub = 0; sub < arregloPunt.length; ++sub)
arregloPunt[sub] += INCREMENTO;

Un error frecuente del programador es intentar usar length como un metodo del arreglo, escribiendo
arregloPunt.length(), en vez de usarlo como un campo. Una variable de instancia o campo objeto
como length es tambien llamado una propiedad del objeto.

Java tambien soporta un ciclo for mejorado. Este ciclo permite recorrer un arreglo sin indicar
los puntos de inicio y terminacion para la variable de control del ciclo. Para mostrar cada elemento
del arreglo llamado arregloPunt con el ciclo avanzado se hace as:

for (int val : arregloPunt)


System.out.println(val);

val es definido del mismo tipo que el arreglo nombrado que esta despues de los dos puntos. Dentro
del ciclo, val adquiere, uno a la vez, cada valor del arreglo. Se puede leer como, Para cada val en
arregloPunt, mostrar val. El ciclo for avanzado es conocido tambien como ciclo foreach.

6
Uso de una parte del arreglo

En ocasiones no se quiere usar cada valor en un arreglo. Por ejemplo, suponer que se escribe un
programa que permite a un estudiante meter hasta 10 puntuaciones y luego calcular y mostrar el
promedio. Para permitir 10 puntuaciones, se crea un arreglo que puede guardar 10 valores, pero
como el estudiante podra meter menos de 10 valores, se podra usar una parte del arreglo, como
se muestra en el codigo 1.

1 import j a v a . u t i l . ;
2 public c l a s s P r o m e d i o F l e x i b l e {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 int [ ] p u n t u a c i o n e s = new int [ 1 0 ] ;
5 int p u n t u a c i o n = 0 ;
6 int c u e n t a = 0 ;
7 int t o t a l = 0 ;
8 f i n a l int SALIR = 9 9 9 ;
9 f i n a l int MAX = 1 0 ;
10 Scanner e n t r a d a = new Scanner ( System . i n ) ;
11 System . out . p r i n t ( Entrar p u n t u a c i on : ) ;
12 puntuacion = entrada . nextInt ( ) ;
13 while ( c u e n t a < MAX && p u n t u a c i o n != SALIR ) {
14 i f ( p u n t u a c i o n != SALIR ) {
15 puntuaciones [ cuenta ] = puntuacion ;
16 t o t a l += p u n t u a c i o n e s [ c u e n t a ] ;
17 System . out . p r i n t ( I n g r e s a r s i g u i e n t e p u n t u a c i on o +
18 SALIR + para s a l i r : ) ;
19 puntuacion = entrada . nextInt ( ) ;
20 }
21 c u e n t a++;
22 }
23 System . out . p r i n t l n ( Las p u n t u a c i o n e s dadas son : ) ;
24 f o r ( int x = 0 ; x < c u e n t a ; ++x )
25 System . out . p r i n t ( p u n t u a c i o n e s [ x ] + ) ;
26 System . out . p r i n t l n ( \n El promedio e s + ( t o t a l 1 . 0 / c u e n t a ) ) ;
27 }
28 }

Codigo 1: Aplicacion PromedioFlexible.

La aplicacion PromedioFlexible declara un arreglo que puede guardar diez puntuaciones. Al usua-
rio se pide la primera puntuacion; luego, en ciclo while la puntuacion es puesta en el arreglo
puntuaciones. Luego la puntuacion es agregada a un total, y al usuario se le pide ingresar otra
puntuacion o un valor SALIR de 999 para parar la peticion de numeros. En el ciclo while se revisa
para que no mas de diez puntuaciones sean ingresadas y que el usuario no de 999 para salir. Des-
pues de cada puntuacion entrada, la variable contar es incrementada, y sirve para dos propositos:
para indicar el elemento donde la siguiente puntuacion debera ser guardada, y para cuando el ciclo
termina saber la cantidad de puntuaciones dadas. La variable count luego es usada para controlar
la salida del ciclo for y para el calculo del promedio.

Actividad 3. Modificar la aplicacion descrita en la actividad 2 para que se use un ciclo for para
mostrar cada uno de los elementos del arreglo.

7
4. Declaracion y uso de arreglos de objetos

Se pueden declarar arreglos que guarden elementos de cualquier tipo, incluyendo objetos. Por
ejemplo, suponer que se ha creado la clase Asalariado, codigo 2, la cual incluye dos campos de
datos, numero y salario, un constructor, y metodos accesores para cada campo.

1 public c l a s s A s a l a r i a d o {
2 private int numero ;
3 private double s a l a r i o ;
4 A s a l a r i a d o ( int n , double s ) {
5 numero = n ;
6 salario = s ;
7 }
8 public int getNumero ( ) {
9 return numero ;
10 }
11 public int g e t S a l a r i o ( ) {
12 return s a l a r i o ;
13 }
14 }

Codigo 2: La clase Asalariado.

Se pueden crear objetos individuales Asalariado con nombres unicos, como los siguientes:

Asalariado pintor, electricista, plomero;


Asalariado trabajador1, trabajador2, trabajador3;

En varios programas puede ser mas conveniente crear un arreglo de objetos Asalariado. Un arreglo
llamado plantilla que guarde siete objetos Asalariado se define como:

Asalariado[] plantilla = new Asalariado[7];

La sentencia reserva suficiente memoria para siete objetos Asalariado llamados plantilla[0]
hasta plantilla[6]. La sentencia no construye los objetos Asalariado, por lo tanto se reque-
rira llamar al constructor siete veces. Se quiere numerar a los trabajadores empezando en 500 y
con un salario de $1,200, y como el constructor de la clase Asalariado requiere dos argumentos,
numero del asalariado y salario, el siguiente ciclo construye los siete objetos:

final int NUM INICIAL = 500;


final double SALARIO = 1200.0;
for (int x = 0; x < plantilla.length; ++x)
plantilla[x] = new Asalariado(NUM INICIAL + x, SALARIO);

Como x vara desde 0 hasta 6, cada uno de los siete objetos plantilla es construido con un
numero de empleado que es 500 mas que x, y con el mismo salario de $1,200.00, como se asigna
por la constante SALARIO.

8
Otras clases contienen solo el constructor por defecto, el cual es dado automaticamente cuando
no hay ningun constructor escrito en la clase. Para construir un arreglo de objetos usando un
constructor por defecto, tambien se debe llamar al constructor usando la palabra reservada new
para cada elemento declarado del arreglo. Por ejemplo, suponer que se ha creado una clase llamado
ArticuloInventario sin haber escrito un constructor. Para crear un arreglo de 1,000 objetos
ArticuloInventario, se podra hacer as:

final int CANT ARTS = 1000;


ArticuloInventario[] articulos = new ArticuloInventario[CANT ARTS];
for (int x = 0; x < CANT ARTS; ++x)
articulos[x] = new ArticuloInventario();

Para usar un metodo que pertenece a un objeto que es parte de un arreglo, se inserta la notacion
subndice apropiada despues del nombre arreglo y antes del punto que precede al nombre del metodo.
Por ejemplo, para mostrar los datos de los siete asalariados guardados en el arreglo plantilla, se
puede escribir lo siguiente:

for (int x = 0; x < plantilla.length; ++x)


System.out.println(plantilla[x].getNumero() + " " +
plantilla[x].getSalario());

La colocacion del subndice entre corchetes es despues de plantilla para indicar que el metodo
pertenece a un elemento particular de la plantilla.

Uso de ciclos for avanzados con objetos

Se puede emplear el ciclo for avanzado para recorrer un arreglo de objetos. Para mostrar los datos
de los siete asalariados guardados en el arreglo plantilla, se puede hacer de esta forma:

for (Asalariado trabajador : plantilla)


System.out.println(trabajador.getNumero() + " " +
trabajador.getSalario());

En este ciclo, trabajador es una variable local que representa cada elemento de plantilla en
turno. Usando el ciclo for avanzado se evita usar un valor limitante para el ciclo y de usar un
subndice siguiendo a cada elemento.

Manipulacion de arreglos de String

Como con cualquier otro objeto, se puede crear un arreglo de objetos String. Por ejemplo, se puede
guardar los nombres de los departamentos de una empresa como sigue:

String[] departNombres = {"Contabilidad", "Recursos Humanos", "Ventas"};

9
Se acceden los nombres de los departamentos como otros arreglos objeto. Por ejemplo, se puede
usar el siguiente codigo para mostrar la lista de String guardadas en el arreglo departNombres:

for (int a = 0; a < departNombres.length; ++a)


System.out.println(departNombres[a]);

Actividad 4. Crear la clase EquipoBaloncesto, la cual contendra un arreglo String para guardar
los nombres, de exactamente cinco jugadores, de un equipo de baloncesto. Cuando se declare el
arreglo en la clase, este debera ser creado. Agregar un metodo que ponga el nombre de un miembro
del equipo. Este metodo requiere una posicion y un nombre, y usa la posicion como subndice al
arreglo String para asignar el nombre. Agregar un metodo accesor que devuelve el nombre de un
miembro del equipo; este metodo requiere un valor usado como subndice para determinar cual
nombre se devuelve del arreglo. Agregar tambien a la clase EquipoBaloncesto un campo String,
para guardar el nombre del equipo; agregar metodo accesor y mutador para este campo. Crear
una aplicacion que muestre de manera completa el uso de la clase EquipoBaloncesto, es decir,
debera declarar y crear un objeto del tipo EquipoBaloncesto, pedir al usuario los nombres del
equipo y mostrar los miembros del equipo.

5. Busqueda y uso de arreglos paralelos

Suponer que una empresa manufactura diez artculos. Cuando un cliente pone una orden se necesita
determinar si la clave del artculo es valida. Cuando se desea determinar si una variable tiene uno
de varios valores validos y estos son secuenciales, por ejemplo entre 201 y 220, la siguiente sentencia
if, que usa el operador logico Y, puede hacer la revision para poner la bandera a true si el artculo
es valido.

final int INF = 201;


final int SUP = 220;
boolean articuloValido = false;
if (articuloOrdenado >= INF && articuloOrdenado <= SUP)
articuloValido = true;

Cuando los valores validos no son secuenciales, por ejemplo, 101, 108, 201, 213, 266, 304, etc., se
puede codificar la siguiente sentencia if anidada profundamente o una comparacion larga O para
determinar la validez.

if (articuloOrdenado == 101)
articuloValido = true;
else if (articuloOrdenado == 108)
articuloValido = true;
else if (articuloOrdenado == 201)
articuloValido = true;
// y as sucesivamente

10
Otra solucion elegante y compacta es comparando la variable articuloOrdenado con una lista de
valores en un arreglo, un proceso llamado busqueda en un arreglo. Se inicializa el arreglo con los
valores validos y luego se emplea la sentencia for para recorrer el arreglo, poniendo una variable
booleana a true cuando un apareamiento es encontrado.

int [] valoresValidos = {101, 108, 201, 213, 266,


304, 311, 409, 411, 412};
for (int x = 0; x < valoresValidos.length; ++x)
if (articuloOrdenado == valoresValidos[x])
articuloValido = true;

El uso del ciclo for en esta solucion permite revisar cualquier cantidad de valores validos sin tener
que modificar ninguna parte, ya que valoresValidos.length tiene el tamano actual del arreglo.

Uso de arreglos paralelos

Cuando se tienen dos arreglos con la misma cantidad de elementos y sus elementos se relacionan
entre ellos por la posicion, entonces se puede usar simultaneamente el mismo subndice en ambos
arreglos.

Un arreglo paralelo es uno con la misma cantidad de elementos como otro y para el cual los
valores en los elementos correspondientes estan relacionados.

Suponiendo que para el codigo mostrado previamente se configura un arreglo que tenga los precios
de los artculos, entonces estos precios deberan aparecer en el mismo orden que sus correspondientes
numeros de artculo en el arreglo valoresValidos. El ciclo for que encuentra el numero valido de
artculo tambien encuentra el precio, como se muestra en la aplicacion EncontrarPrecio, codigo
3.

11
1 import j a v a x . swing . JOptionPane ;
2 public c l a s s E n c o n t r a r P r e c i o {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 int [ ] v a l o r e s V a l i d o s = { 1 0 1 , 1 0 8 , 2 0 1 , 2 1 3 , 2 6 6 ,
5 304 , 311 , 409 , 411 , 412};
6 double [ ] p r e c i o s = { 2 2 . 5 , 1 3 . 6 0 , 1 8 . 7 0 , 5 4 . 2 0 , 2 3 . 3 0 ,
7 54.80 , 56.20 , 78.90 , 5.50 , 9.90};
8 String articuloStr ;
9 int a r t i c u l o O r d e n a d o ;
10 double p r e c i o A r t i c u l o = 0 . 0 ;
11 boolean a r t i c u l o V a l i d o = f a l s e ;
12 a r t i c u l o S t r = JOptionPane . sh ow In pu tD ia lo g ( null ,
13 I n g r e s a r e l numero de a r t c u l o que q u i e r e o r d e n a r ) ;
14 articuloOrdenado = Integer . parseInt ( a r t i c u l o S t r ) ;
15 f o r ( int i =0; i <v a l o r e s V a l i d o s . l e n g t h ; ++i )
16 i f ( a r t i c u l o O r d e n a d o == v a l o r e s V a l i d o s [ i ] ) {
17 a r t i c u l o V a l i d o = true ;
18 precioArticulo = precios [ i ] ;
19 }
20 if ( articuloValido )
21 JOptionPane . showMessageDialog ( null , El p r e c i o d e l a r t c u l o +
22 articuloOrdenado + es $ + p r e c i o A r t i c u l o ) ;
23 else
24 JOptionPane . showMessageDialog ( null ,
25 Lo s i e n t o ! , a r t c u l o i n g r e s a d o no va l i d o ) ;
26 }
27 }

Codigo 3: La aplicacion EncontrarPrecio que accede informacion en arreglos paralelos.

Nota. En lugar de arreglos paralelos conteniendo numeros de artculos y precios, se puede crear una
clase llamada Articulo conteniendo dos campos, articuloOrdenado y precioArticulo. Luego
se crea un arreglo simple de objetos que encapsulan los numeros y los precios.

En el codigo 3 se compara articuloOrdenado con cada uno de los diez valoresValidos. No


importa, que por ejemplo, articuloOrdenado sea igual al primer valor, se terminan haciendo
nueve comparaciones extras, y estas seran siempre falsas. Tan pronto como un apareamiento para
articuloOrdenado es encontrado, es mas eficiente forzar la salida temprana del ciclo for. Una
forma facil de lograrlo es poner x a un valor alto dentro del bloque de sentencias ejecutadas cuando
hay un apareamiento. Enseguida se muestra la forma como se puede hacer. Tambien considerar
para una mayor eficiencia poner los artculos mas comunes al inicio.

for (int x = 0; x < CANTIDAD DE ARTICULOS; ++x)


if (articuloOrdenado == valoresValidos[x]) {
articuloValido = true ;
precioArticulo = precios[x];
x = CANTIDAD DE ARTICULOS;
}

Algunos programadores consideran inapropiado modificar la variable de control de ciclo dentro del

12
Cantidad ordenada Descuento
1 a 12 Ninguno
13 a 49 10 %
50 a 99 14 %
100 a 199 18 %
200 o mas 20 %

Cuadro 1: Tabla de descuentos

cuerpo del ciclo for; porque consideran que solo se debe hacer en la tercera seccion del ciclo for.
Por lo que la salida forzada del ciclo la realizan con otra expresion booleana en la seccion central
del ciclo for, de esta forma, como se muestra enseguida, x debera estar entre el rango antes de
cada iteracion y articuloValido no debera estar puesta a true.

for (int x = 0; x < CANTIDAD DE ARTICULOS && !articuloValido; ++x)


if (articuloOrdenado == valoresValidos[x]) {
articuloValido = true ;
precioArticulo = precios[x];
}

Busqueda en un arreglo por un rango de apareamiento

Suponga ahora que una empresa da descuentos a sus clientes de acuerdo a la cantidad de artculos
ordenados. El cuadro 1 muestra el descuento ofrecido dependiendo de la cantidad ordenada.

Una opcion de programacion ineficiente es crear un arreglo simple para guardar los descuentos. Se
podra usar una variable llamada cantArts como subndice en el arreglo, pero el arreglo podra
requerir cientos de entradas, como se muestra enseguida:

double [] descuentos = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,


0.10, 0.10, 0.10, ...};

En el arreglo descuentos se requieren trece ceros, porque el primer elemento del arreglo tiene un
subndice cero y representa un descuento de cero para cero artculos y los siguientes 12 descuentos
tambien son cero para manejar desde un artculo hasta 12. Despues el arreglo guardara 37 copias
de 0.10 para 13 artculos y hasta 49. El arreglo sera necesariamente grande para guardar un valor
exacto para cada posible cantidad ordenada.

Una mejor opcion es crear dos arreglos correspondientes y realizar un apareamiento de rango, en
el cual se compara un valor con los extremos de los rangos numericos para encontrar la categora a
la cual el valor pertenece. Por ejemplo, un arreglo puede tener los cinco descuentos, y el otro arreglo
puede tener los cinco lmites inferiores de los rangos de descuento, como se muestra enseguida:

int [] limitesInferiores = {1, 13, 50, 100, 200};


double [] descuentos = {0, 0.1, 0.14, 0.18, 0.2};

13
Empezando con el ultimo elemento del arreglo limitesInferiores, para cualquier cantOrdenada
mayor que, o igual a limitesInferiores[4], el descuento es descuentos[4]. Si cantOrdenada
es menor que limitesInferiores[4], se debera decrementar el subndice y buscar en un rango
inferior. En la aplicacion EncontrarDescuento, codigo 4, se muestra el uso de los arreglos paralelos
anteriores.
1 import j a v a x . swing . JOptionPane ;
2 public c l a s s E n c o n t r a r D e s c u e n t o {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 f i n a l int CANT RANGOS = 5 ;
5 int [ ] l i m i t e s I n f e r i o r e s = { 1, 13 , 50 , 100 , 200};
6 double [ ] d e s c u e n t o s = { 0 , 0 . 1 , 0 . 1 4 , 0 . 1 8 , 0 . 2 } ;
7 double d e s c u e n t o C l i e n t e ;
8 S t r i n g strCantOrdenada ;
9 int cantOrdenada ;
10 int sub = CANT RANGOS 1 ;
11 strCantOrdenada = JOptionPane . s ho wI np ut Di al og ( null ,
12 Cua n t o s a r t c u l o s ha ordenado ? ) ;
13 cantOrdenada = I n t e g e r . p a r s e I n t ( strCantOrdenada ) ;
14 while ( sub >= 0 && cantOrdenada < l i m i t e s I n f e r i o r e s [ sub ] )
15 sub ;
16 d e s c u e n t o C l i e n t e = d e s c u e n t o s [ sub ] ;
17 JOptionPane . showMessageDialog ( null , El d e s c u e n t o para +
18 cantOrdenada + a r t c u l o s e s + d e s c u e n t o C l i e n t e ) ;
19 }
20 }

Codigo 4: La aplicacion EncontrarDescuento.

Nota. En la aplicacion EncontrarDescuento, codigo 4, se require que sub sea mayor que, o igual
a cero antes de evaluar la expresion booleana cantOrdenada <limitesInferiores[sub]. Es un
buen habito de programacion asegurarse que un subndice para un arreglo no caiga por debajo de
cero, ya que causara un error en tiempo de ejecucion.

Actividad 5. Modificar la actividad 4 para permitir que se capturen varios equipos de baloncesto,
y despues se le pida al usuario el nombre de algun equipo del que quiera ver sus jugadores.

6. Paso y devolucion de arreglos en metodos

Se puede usar cualquier elemento de un arreglo de la misma forma como se usa cualquier variable
del mismo tipo. De igual forma, se puede pasar un elemento de un arreglo a un metodo de la misma
forma como se pasa una variable.

La aplicacion PasarElementoArreglo, codigo 5, crea un arreglo de cuatro enteros y los muestra.


La aplicacion llama el metodo obtenerUnEntero() cuatro veces, pasando un elemento a la vez.
El metodo muestra el numero, cambia el numero a 999, y luego muestra el numero otra vez.
Finalmente, de regreso en el metodo main(), los cuatro numeros son mostrados otra vez.

14
1 public c l a s s P a s a r E l e m e n t o A r r e g l o {
2 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
3 int [ ] numeros = { 1 0 , 2 0 , 3 0 , 4 0 } ;
4 System . out . p r i n t ( Al i n i c i o de main : ) ;
5 f o r ( int n : numeros )
6 System . out . p r i n t ( + n ) ;
7 System . out . p r i n t l n ( ) ;
8 f o r ( int i =0; i <numeros . l e n g t h ; ++i )
9 obtenerUnEntero ( numeros [ i ] ) ;
10 System . out . p r i n t ( Al f i n a l de main : ) ;
11 f o r ( int n : numeros )
12 System . out . p r i n t ( + n ) ;
13 System . out . p r i n t l n ( ) ;
14 }
15 public s t a t i c void obtenerUnEntero ( int uno ) {
16 System . out . p r i n t ( Al i n i c i o d e l metodo ((uno)) e s : + uno ) ;
17 uno = 9 9 9 ;
18 System . out . p r i n t l n ( y a l f i n a l d e l metodo ((uno)) e s : + uno ) ;
19 }
20 }

Codigo 5: La aplicacion PasarElementoArreglo.

Al ejecutar la aplicacion PasarElementoArreglo, se puede ver que los cuatro numeros pasados
fueron cambiados en el metodo obtenerUnEntero() permanecen sin cambio de regreso en main()
despues de la ejecucion del metodo. La variable llamada uno es local al metodo obtenerUnEntero,
y cualquier cambio a variables pasadas en el metodo no son permanentes y no son reflejados en el
arreglo en el metodo main(). Cada variable llamada uno en el metodo obtenerUnEntero guarda
una sola copia del elemento del arreglo pasado al metodo. Los elementos individuales del arreglo
son pasados por valor; es decir, una copia del valor es hecha y usada dentro del metodo receptor.
Cuando cualquier tipo primitivo, boolean, char, byte, short, int, long, float, o double, es
pasado a un metodo, el valor es pasado.

Los arreglos, como todos los objetos no primitivos, son tipos de referencia, esto es, el objeto
guarda una direccion de memoria donde los valores estan guardados. Como un arreglo es una
referencia, no se puede asignar otro arreglo a este usando el operador =, ni se pueden comparar
dos arreglos usando el operador ==. Cuando se pasa un arreglo, se pasa su nombre, a un metodo,
el metodo receptor obtiene una copia de la direccion de memoria actual del arreglo. Por lo tanto el
metodo receptor tiene acceso a los valores originales del arreglo de elementos del metodo llamador.

La aplicacion PasarArreglo, codigo 6, crea un arreglo de cuatro enteros. Despues que los enteros son
mostrados, el nombre del arreglo, su direccion, es pasado a un metodo llamado obtieneArreglo().
Dentro del metodo, los numeros son mostrados, para observar que estos retienen sus valores des-
de main(), luego el valor 888 esta asignado a cada numero. A pesar de que obtieneArreglo()
es un metodo void, no devuelve nada al metodo main(), cuando el metodo main() muestra el
arreglo por segunda ocasion, todos los valores han sido cambiados a 888. Ejecutar la aplicacion
PasarArreglo para comprobar lo comentado. Como el metodo recibe una referencia del arreglo, el
metodo obtieneArreglo() sabe la direccion del arreglo declarado en main() y hace sus cambios
directamente al arreglo original.

15
1 public c l a s s P a s a r A r r e g l o {
2 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
3 int [ ] numeros = { 1 0 , 2 0 , 3 0 , 4 0 } ;
4 System . out . p r i n t ( Al i n i c i o de main : ) ;
5 f o r ( int n : numeros )
6 System . out . p r i n t ( + n ) ;
7 System . out . p r i n t l n ( ) ;
8 o b t i e n e A r r e g l o ( numeros ) ;
9 System . out . p r i n t ( Al f i n a l de main : ) ;
10 f o r ( int n : numeros )
11 System . out . p r i n t ( + n ) ;
12 System . out . p r i n t l n ( ) ;
13 }
14 public s t a t i c void o b t i e n e A r r e g l o ( int [ ] a r r ) {
15 System . out . p r i n t ( Al i n i c i o d e l metodo a r r t i e n e : ) ;
16 f o r ( int n : a r r )
17 System . out . p r i n t ( + n ) ;
18 System . out . p r i n t l n ( ) ;
19 f o r ( int i =0; i <a r r . l e n g t h ; ++i )
20 arr [ i ] = 888;
21 System . out . p r i n t ( Al f i n a l d e l metodo a r r t i e n e : ) ;
22 f o r ( int n : a r r )
23 System . out . p r i n t ( + n ) ;
24 System . out . p r i n t l n ( ) ;
25 }
26 }

Codigo 6: La aplicacion PasarArreglo.

Nota. En otros lenguajes, como C, C++, y C#, se puede escoger pasar variables a metodos por
valor o referencia. No se puede escoger en Java. Las variables tipo primitivo son siempre pasadas por
valor. Cuando se pasa un objeto, una copia de la referencia al objeto es siempre pasada.

Regresar un arreglo desde un metodo

Un metodo puede regresar una referencia arreglo. Cuando un metodo regresa una referencia arreglo,
se deben incluir corchetes con el tipo regresado en la cabecera del metodo. En el siguiente codigo se
muestra el metodo getArreglo() que regresa un arreglo de int declarado localmente. Los corchetes
son usados como parte del tipo regresado; la sentencia return devuelve el nombre del arreglo sin
ningun corchetes.

public static int [] getArreglo() {


int [] puntuaciones = {98, 74, 69, 89};
return puntuaciones;
}

Cuando se llama al metodo getArreglo() que se muestra previamente, se puede guardar su valor
devuelto en cualquier referencia arreglo entero. Por ejemplo, se podra declarar un arreglo y hacer
la llamada del metodo en la siguiente sentencia:

16
int [] puntuacionesRecibidas = getArreglo();

Actividad 6. Agregar a la actividad 5 un metodo que devuelva un arreglo de 5 equipos de ba-


loncesto. En el metodo se pedira el nombre del equipo y los nombres de los jugadores para cada
uno de los equipos. Agregar en el metodo main() la llamada a este metodo que crea los equipos de
baloncesto.

17

You might also like