You are on page 1of 22

Arreglos Avanzados

H. Tejeda

Marzo 2016

Indice

1. Ordenamiento de elementos de un arreglo 1

2. Arreglos multidimensionales 7

3. Clase Arrays 11

4. Clase ArrayList 14

5. Enumeraciones 18

Se presentan a continuacion algunas otras operaciones que son realizadas con los arreglos. Una
en particular, el ordenamiento de los elementos, es requerida por otros algoritmos. Tambien se
indica como declarar y crear arreglos con mas de una dimension. Se revisa la clase Arrays que
tiene metodos para algunas de las operaciones requeridas en un arreglo, como el ordenamiento.
Por su parte la clase ArrayList es una clase que permite realizar algunas operaciones adicionales
que no estan presentes cuando se maneja un arreglo directamente. Por ultimo se comentan las
enumeraciones que son empleadas para crear un tipo de dato propio con un conjunto fijo de valores
validos.

1. Ordenamiento de elementos de un arreglo

El ordenamiento es el proceso de arreglar una serie de objetos con algun orden logico. Cuando
se ponen los objetos en orden, iniciando con el objeto que tiene el menor valor, se esta haciendo
en orden ascendente, y si se inicia con el objeto con el valor mas grande, se hace en orden
descendente.

El ordenamiento posible mas simple es el de dos valores que no esten ordenados. Se deben inter-
cambiar los dos valores para ponerlos en orden. Suponiendo que se tienen dos variables, valA y
valB, con los valores 16 y 2, respectivamente. Para intercambiar los valores se requiere usar una
variable temp para que no se pierdan los valores al intercambiar, as el codigo quedara como:

1
temp = valA; // 16 se asigna a temp
valA = valB; // 2 se asigna a valA
valB = temp; // 16 se asigna a valB

Si se quiere ordenar dos valores cualesquiera, valA y valB, en orden ascendente, se usa la siguiente
sentencia if para decidir si se hace el intercambio. El intercambio se hace cuando valA es mayor
que valB, de otra forma no se hace nada.

if (valA > valB) {


temp = valA;
valA = valB;
valB = temp;
}

Ordenar mas de dos valores puestos en variables es mas complicado, pero esta tarea es manejable
cuando se usa un arreglo.

Varios algoritmos de ordenamiento han sido desarrollados; un algoritmo es un proceso o conjunto


de pasos que resuelven un problema.

Algoritmo de ordenamiento burbuja

En el algoritmo de ordenamiento burbuja se comparan parejas de elementos contiguos, inter-


cambiandolos si no estan ordenados. as los elementos mas pequenos burbujean a la cima de la
lista, eventualmente creando una lista ordenada. El ordenamiento burbuja ni es el mas rapido, ni
la tecnica mas eficiente de ordenamiento, pero es facil de entender y da mayor conocimiento de la
manipulacion de elementos del arreglo.

Suponiendo que se tienen valores no ordenados en un arreglo, como en el siguiente codigo:

int [] numeros = {88, 33, 99, 22, 54};

Se compara el primer numero con el segundo, si no estan ordenados ascendentemente se intercam-


bian. Luego se repite lo anterior para el segundo con el tercero, y as sucesivamente, hasta terminar
con el cuarto y el quinto. En general se compara si numeros[x] es mayor que numeros[x + 1]
para intercambiarlos. En la siguiente tabla se muestran en la primera columna los numeros que son
comparados, la segunda columna informa si la pareja de valores son intercambiados y la ultima
muestra los valores del arreglo como van acomodando.

Valores Arreglo
comparados Intercambio? numeros
88 > 33 S 88, 33, 99, 22, 54
88 > 99 No 33, 88, 99, 22, 54
99 > 22 S 33, 88, 99, 22, 54
99 > 54 S 33, 88, 22, 99, 54
33, 88, 22, 54, 99

2
Cuando se alcanza el fondo de la lista, los numeros no estan en orden ascendente, pero el numero
mas grande, 99, se ha movido al fondo de la lista. Esta caracterstica da al ordenamiento burbuja
su nombre, el valor mas pesado se ha hundido en el fondo de la lista y los valores mas ligeros
han burbujeado a la cima.

Suponiendo que b y temp han sido declaradas como variables enteras, el codigo para lo realizado
previamente es:

for (b = 0; b < numeros.length - 1; ++b)


if (numeros[b] > numeros[b+1]) {
temp = numeros[b];
numeros[b] = numeros[b+1];
numeros[b+1] = temp;
}

Nota. En vez de comparar b con numeros.length - 1 en cada iteracion del ciclo, es mas eficiente
declarar una variable a la cual se le asigne numeros.length - 1 y usarla en la comparacion. De
esta forma, la resta es hecha una sola vez.

Para continuar el ordenamiento de la lista se debe hacer nuevamente el procedimiento de compa-


racion-intercambio, en la siguiente tabla se describe el procedimiento.

Valores Arreglo
comparados Intercambio? numeros
33 > 88 No 33, 88, 22, 54, 99
88 > 22 S 33, 88, 22, 54, 99
88 > 54 S 33, 22, 88, 54, 99
88 > 99 No 33, 22, 54, 88, 99
33, 22, 54, 88, 99

Se puede observar que con una pasada mas en la lista, los valores 22 y 33 se intercambiaran, y
la lista quedara en orden. Para ordenar completamente la lista en el pero caso, una en la cual
los numeros originales esten en orden descendente, se requiere ir en la lista cuatro veces con el
procedimiento comparacion-intercambio. A lo mas, siempre se necesitara pasar por la lista tantas
veces como su tamano menos uno. El siguiente codigo muestra el procedimiento completo.

for (a = 0; a < numeros.length - 1; ++a)


for (b = 0; b < numeros.length - 1; ++b)
if (numeros[b] > numeros[b+1]) {
temp = numeros[b];
numeros[b] = numeros[b+1];
numeros[b+1] = temp;
}

Al usar el ordenamiento burbuja para ordenar cualquier arreglo en orden ascendente, el valor mas
grande cae en el fondo del arreglo despues de comparar cada par de valores consecutivos en el

3
arreglo una vez. La segunda vez que se recorre el arreglo haciendo comparaciones, no hay necesidad
de revisar el ultimo par. Se garantiza que el valor mas grande ya esta en el fondo del arreglo. Se
puede hacer el proceso de ordenamiento mas eficiente usando una variable nueva para el ciclo for
interno y reduciendo el valor en uno en cada ciclo a traves del arreglo. El siguiente codigo muestra
como se realiza.

int comparaciones = numeros.length - 1;


for (a = 0; a < numeros.length - 1; ++a) {
for (b = 0; b < comparaciones; ++b)
if (numeros[b] > numeros[b+1]) {
temp = numeros[b];
numeros[a] = numeros[b];
numeros[b] = temp;
}
--comparaciones;
}

Ordenamiento de arreglos de objetos

Se pueden ordenar arreglos de objetos de la misma forma como se ordenan arreglos de tipos pri-
mitivos. La diferencia principal se da cuando se hace la comparacion que determina si se hace el
intercambio de dos elementos del arreglo. Con un arreglo de elementos primitivos, se comparan los
dos elementos del arreglo para saber si estan desordenados. Cuando los elementos del arreglo son
objetos, se ordena usando un campo particular del objeto.

Suponer que se ha creado una clase simple EmpleadoCompleto, codigo 1. La clase tiene cuato
campos de datos y los metodos set y get para los campos.

4
1 public c l a s s EmpleadoCompleto {
2 private int numero ;
3 private S t r i n g a p e l l i d o s ;
4 private S t r i n g nombres ;
5 private double s a l a r i o ;
6 public int getNumero ( ) {
7 return numero ;
8 }
9 public S t r i n g g e t A p e l l i d o s ( ) {
10 return a p e l l i d o s ;
11 }
12 public S t r i n g getNombres ( ) {
13 return nombres ;
14 }
15 public double g e t S a l a r i o ( ) {
16 return s a l a r i o ;
17 }
18 public void setNumero ( int num ) {
19 numero = num ;
20 }
21 public void s e t A p e l l i d o s ( S t r i n g aps ) {
22 a p e l l i d o s = aps ;
23 }
24 public void setNombres ( S t r i n g nom ) {
25 nombres = nom ;
26 }
27 public void s e t S a l a r i o ( double s a l ) {
28 salario = sal ;
29 }
30 }

Codigo 1: Clase EmpleadoCompleto.

Se puede escribir un programa que contenga un arreglo de cinco objetos EmpleadoCompleto usando
la siguiente sentencia:

EmpleadoCompleto[] empleados = new EmpleadoCompleto[5];

Despues de asignar los numeros de empleado, nombres y salarios a los objetos EmpleadoCompleto,
se quiere ordenar los empleados por el salario. Se puede pasar el arreglo a un metodo ordenaBurbuja
que esta preparado para recibir el arreglo de EmpleadoCompleto, enseguida se muestra el metodo.

public static void ordenaBurbuja(EmpleadoCompleto[] arreglo) {


int a, b;
EmpleadoCompleto temp;
int comparaciones = arreglo.length - 1;
for (a = 0; a < arreglo.length - 1; ++a) {
for (b = 0; b < comparaciones; ++b)
if (arreglo[b].getSalario() > arreglo[b+1].getSalario()) {
temp = arreglo[b];

5
arreglo[b] = arreglo[b+1];
arreglo[b+1] = temp;
}
--comparaciones;
}
}

El metodo ordenaBurbuja es similar al metodo usado para un arreglo de tipos primitivos, pero
hay tres diferencias.

La cabecera del metodo ordenaBurbuja muestra que recibe un arreglo de tipo EmpleadoCompleto.

La variable temp creada para intercambiar es del tipo EmpleadoCompleto. Observar que a
pesar de solo los salarios de los empleados completos son comparados, no se intercambian
unicamente los salarios, se intercambian cada objeto EmpleadoCompleto.

La comparacion para determinar si un intercambio se hace usa llamadas al metodo getSalario()


para comparar el salario de cada objeto en el arreglo con el salario del objeto adyacente.

Actividad 1. Crear una aplicacion que pida al usuario 5 numeros enteros que seran guardados en
un arreglo. Despues usara el metodo de la burbuja para ordenar en forma ascendente los elementos,
y en cada iteracion del ciclo externo del metodo de la burbuja debera mostrar los elementos del
arreglo con la finalidad de que el usuario pueda observar los valores conforme son reposicionados
en el arreglo.

Algoritmo de ordenamiento por insercion

El ordenamiento burbuja es facil de entender y manipular, pero existen otros algoritmos de orde-
namiento. El algoritmo ordenamiento por insercion revisa cada elemento de la lista uno a la
vez. Si un elemento esta desordenado respecto a cualquiera de los elementos previos, se mueve cada
elemento previo hacia abajo una posicion y se inserta el elemento revisado. Este ordenamiento es
similar a la tecnica que sera mas probable de usar para ordenar un grupo de objetos manualmente.
Por ejemplo, si una lista contiene los valores 2, 3, 1, y 4, y se quiere poner en orden ascendente se
prueban los valores 2 y 3, pero no se mueven porque estan en orden. Cuando se prueba el tercer
valor, 1, se mueven 2 y 3 a posiciones posteriores y se inserta 1 a la primera posicion.

El siguiente codigo muestra la logica que realiza un ordenamiento por insercion ascendente usando
un arreglo de enteros de 5 elementos llamado numeros. Se supone que a, b, y temp han sido
declarados como enteros.

int [] numeros = {90, 85, 65, 95, 75};


a = 1;
while (a < numeros.length) {
temp = numeros[a];
b = a - 1;
while (b >= 0 && numeros[b] > temp) {

6
numeros[b + 1] = numeros[b];
--b;
}
numeros[b + 1] = temp;
++a;
}

El ciclo externo del codigo anterior modifica una variable de control de ciclo a desde 1 hasta uno
menos que el tamano del arreglo. En el ciclo interno se van recorriendo los elementos de la lista
parcialmente ordenada, empezando por el mayor, si estos son mayores que el elemento que se
revisa. Este movimiento de los elementos es para generar un espacio dentro de la lista parcialmente
ordenada donde sera puesto el elemento revisado. Si el elemento revisado es mayor que el elemento
mas grande de la lista parcialmente ordenada, entonces no se hace ningun cambio a la lista.

En la siguiente tabla se muestra como funciona el algoritmo de ordenamiento por insercion, en la


primera columna se muestra la lista parcial ordenada, en la segunda el elemento que se esta revi-
sando, en la tercera se indica si el elemento esta ordenado y en la cuarta columna se muestra como
se queda el hueco en la lista parcialmente ordenada para poner el elemento que se revisa.

Lista parcial Elemento revisado Lista parcial


ordenada a en orden? modificada
90 85 no , 90
85, 90 65 no , 85, 90
65, 85, 90 95 s 65, 85, 90,
65, 85, 90, 95 75 no 65, , 85, 90, 95
65, 75, 85, 90, 95

Actividad 2. Escribir una aplicacion que solicite al usuario al menos cinco numeros y los ordene
mediante el algoritmo de ordenamiento por insercion.

2. Arreglos multidimensionales

Un arreglo declarado y creado por una sentencia como la siguiente:

int [] numeros = new int [3];

se puede considerar como una columna de valores

numeros[0]
numeros[1]
numeros[2]

y cuyos elementos son accedidos usando un solo subndice, es un arreglo unidimensional o de


una dimension. Se puede pensar en el tamano del arreglo como su altura.

7
Java tambien soporta arreglos de dos o mas dimensiones. Los arreglo bidimensionales tienen dos
o mas columnas de valores como se muestra en el cuadro 1. Las dos dimensiones representan la altura
y el ancho del arreglo. Otra forma de ver un arreglo bidimensional es como un arreglo de arreglos.
Se deben usar dos subndices cuando se accede un elemento en un arreglo bidimensional. Los
matematicos llaman a un arreglo bidimensional una matriz o una tabla. Un arreglo bidimensional
se usa en las hojas de calculo electronicas, como Excel.

numeros[0][0] numeros[0][1] numeros[0][2] numeros[0][3]


numeros[1][0] numeros[1][1] numeros[1][2] numeros[1][3]
numeros[2][0] numeros[2][1] numeros[2][2] numeros[2][3]

Cuadro 1: representacion de un arreglo bidimensional.

Para declarar un arreglo bidimensional se ponen dos juegos de corchetes despues del tipo de arreglo.
Por ejemplo, para el arreglo del cuadro 1 puede ser declarado como sigue, creando el arreglo llamado
numeros que tiene tres renglones y cuatro columnas:

int [][] numeros = new int [3][4];

Si no se proporcionan valores para los elementos en el arreglo bidimensional numerico, los valores
por defecto son cero. Se puede asignar otros valores a los elementos despues. Por ejemplo para
poner el valor catorce al elemento del arreglo numeros que esta en la primera columna del primer
renglon se pone como numeros[0][0] = 14;.

Alternativamente, se puede inicializar un arreglo bidimensional con valores cuando es creado. El


siguiente codigo asigna valores a numeros al declarar el arreglo:

int [][] numeros = { { 0, 2, 4, 6},


{ 8, 10, 12, 14},
{16, 18, 20, 22} };

El arreglo numeros contiene tres renglones y cuatro columnas. Se contiene el conjunto entero de
valores dentro de un juego de corchetes internos.El primer renglon del arreglo tiene los cuatro
enteros 0, 2, 4, y 6. Observar que estos cuatro valores estan puestos dentro de su propio juego de
llaves interno para indicar que forman el primer renglon o el renglon cero. De igual forma se indican
el resto de los renglones usando sus propios juegos de llaves. El valor de numeros[0][0] es 0, de
numeros[0][1] es 2 y el de numeros[2][3] es 22. El valor dentro del primer juego de corchetes
que siguen el nombre del arreglo se refiere al renglon; el valor dentro de los segundos corchetes se
refiere a la columna.

Un ejempo de como puede emplearse un arreglo bidimensional es el siguiente. Suponer que se tiene
un edificio de departamentos con cuatro niveles, la planta baja sera referida como el piso cero, y los
otros tres pisos como el uno, dos, y tres. Ademas cada uno de los pisos tiene estudio (sin recamara)
y departamentos con una y dos recamaras. La renta mensual para cada tipo de departamento
vara, entre mas alto es el piso, mayor es la renta, y la renta es mayor para departamentos con mas
recamaras. La siguiente tabla muestra los montos de las rentas.

8
Sin Una Dos
Piso recamara recamara recamaras
0 4000 4500 5100
1 5000 5600 6300
2 6250 6760 7400
3 10000 12500 16000

Para determinar la renta de algun inquilino, se necesita saber dos cosas: el piso en el cual el inquilino
renta el departamento y la cantidad de recamaras en el departamento. Dentro de un programa Java,
se puede declarar un arreglo de rentas usando el siguiente codigo:

int [][] rentas = { {4000, 4500, 5100},


{5000, 5600, 6300},
{6250, 6760, 7400},
{10000,12500,16000} };

Si se declaran dos enteros llamados piso y recamaras, entonces cualquier renta de un inquilino
puede ser referida como rentas[piso][recamaras]. El codigo 2 muestra una aplicacion que pide
al usuario el numero del piso y la cantidad de recamaras.

1 import j a v a x . swing . JOptionPane ;


2 public c l a s s EncontrarRenta {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 int [ ] [ ] r e n t a s = { { 4 0 0 0 , 4 5 0 0 , 5 1 0 0 } ,
5 {5000 , 5600 , 6300} ,
6 {6250 , 6760 , 7400} ,
7 {10000 ,12500 ,16000} } ;
8 String entrada ;
9 int p i s o , r e c a m a ra s ;
10 e n t r a d a = JOptionPane . sh ow In put Di al og ( null ,
11 I n g r e s e e l numero d e l p i s o ) ;
12 piso = Integer . parseInt ( entrada ) ;
13 e n t r a d a = JOptionPane . sh ow In put Di al og ( null ,
14 I n g r e s e e l numero de r e c amaras ) ;
15 recamaras = I n t e g e r . p a r s e I n t ( entrada ) ;
16 JOptionPane . showMessageDialog ( null ,
17 La r e n t a d e l departamento con + r e c a m a r a s +
18 r e c amara ( s ) en e l p i s o + p i s o + e s $ +
19 r e n t a s [ p i s o ] [ recamaras ] ) ;
20 }
21 }

Codigo 2: Aplicacion EncontrarRenta.

Pasar un arreglo bidimensional a un metodo

Para pasar un arreglo bidimensional a un metodo, solo se pasa el nombre del arreglo al igual como
se hace con un arreglo unidimensional. Un metodo que recibe un arreglo bidimensional usa dos

9
pares de corchetes siguiendo al tipo de dato en la lista de parametros de la cabecera del metodo.
Por ejemplo, las siguientes cabeceras de metodos aceptan arreglos bidimensionales de int, double,
y Empleado, respectivamente:

public static void mostrarPuntuaciones(int [][] puntuaciones)


public static boolean sonTodosPreciosAltos(double [][] precios)
public static double calcularTotalNomina(Empleado[][] plantilla)

Observar que los corchetes indicando el arreglo en la cabecera del metodo estan vacos. No hay
necesidad de poner numeros en los corchetes porque cada nombre de arreglo pasado es una direccion
de memoria inicial. La forma como se manipulan los subndices dentro del metodo determina como
los renglones y columnas son accedidas.

Campo length con un arreglo bidimensional

En un arreglo unidimensional tiene un campo length que guarda la cantidad de elementos en el


arreglo. Con un arreglo bidimensional, el campo length guarda la cantidad de renglones en el
arreglo. A su vez cada renglon tiene un campo length que guarda la cantidad de columnas en el
renglon. Suponiendo que se declara un arreglo rentas como sigue:

int [][] rentas = { {4000, 4500, 5100},


{5000, 5600, 6300},
{6250, 6760, 7400},
{10000,12500,16000} };

El valor de rentas.length es cuatro porque hay cuatro renglones en el arreglo. El valor de


rentas[0].length es tres porque hay tres columnas en el primer renglon del arreglo rentas.
Este valor es igual para el resto de los renglones.

El codigo 3 muestra una aplicacion que usa los campos length asociados con el arreglo rentas
para mostrar todas las rentas. La variable piso vara desde 0 hasta tres en el ciclo externo, y la
variable recamara va desde 0 hasta 2 en el ciclo interno.
1 public c l a s s MostrarRentas {
2 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
3 int [ ] [ ] r e n t a s = { { 4 0 0 0 , 4 5 0 0 , 5 1 0 0 } ,
4 {5000 , 5600 , 6300} ,
5 {6250 , 6760 , 7400} ,
6 {10000 ,12500 ,16000} } ;
7 int p i s o , r e c a m a ra s ;
8 f o r ( p i s o = 0 ; p i s o < r e n t a s . l e n g t h ; ++p i s o )
9 f o r ( r e c a m a r a s = 0 ; r e ca m a r a s < r e n t a s [ p i s o ] . l e n g t h ; ++r e c a m a r a s )
10 System . out . p r i n t l n ( P i s o + p i s o + Recamaras +
11 r e c a m a r a s + Renta e s $ + r e n t a s [ p i s o ] [ r e c a m a r a s ] ) ;
12 }
13 }

Codigo 3: Aplicacion MostrarRentas.

10
En un arreglo bidimensional, cada renglon tambien es un arreglo. Se puede declarar en Java cada
renglon para que tenga diferente longitud. Cuando un arreglo bidimensional tiene renglones de
longitudes diferentes, este es un arreglo imperfecto porque al dibujar las terminaciones de cada
renglon quedan desiguales. Se crea un arreglo imperfecto definiendo la cantidad de renglones para
un arreglo bidimensional, pero no definiendo la cantidad de columnas en los renglones. Por ejemplo,
suponer que se quieren guardar los primeros cinco renglones del Triangulo de Pascal. Se podra
definir el arreglo como sigue:

int [][] triangulo = new int [5][];

La sentencia declara un arreglo con cinco renglones, pero los renglones no han sido creados todava.
Enseguida, se puede declarar los renglones individuales, dependiendo de cuantos valores tiene cada
renglon en el triangulo de Pascal, se usa un ciclo for para escribir un codigo compacto.

for (int i = 0; i < triangulo.length; ++i)


triangulo[i] = new int [i + 1];

Actividad 3. Crear la aplicacion que ponga en un arreglo imperfecto los primeros cinco renglones
del triangulo de Pascal y muestre los valores.

Arreglos multidimensionales

Java tambien soporta arreglos con tres, cuatro y mas dimensiones. El termino general para arreglos
con mas de una dimension es arreglos multidimensionales. Un arreglo de mas de dos dimensiones
se requiere cuando se quiere guardar las rentas de departamentos de varios edificios. Una expresion
como rentas[edificio][piso][recamaras] se refiere a una renta especfica para un edificio cuyo
numero de edificio es guardada en la variable edificio y cuyos numeros piso y recamaras estan
guardadas en las variables piso y recamaras. Java permite crear arreglos de cualquier tamano
siempre y cuando se tenga control de las variables que se ocupan como subndices, y no se agote la
memoria de la computadora.

Actividad 4. Crear una aplicacion que cree un arreglo bidimensional de cuatro renglones por
cuatro columnas. La aplicacion pide un renglon o 99 para salir y una columna, entonces agrega uno
al elemento escogido, luego muestra los 16 elementos en forma matricial y se vuelve a pedir renglon
y columna. Inicialmente todos los elementos en el arreglo tienen cero.

3. Clase Arrays

En muchas ocasiones se quiere realizar tareas similares con arreglos diferentes, por ejemplo, llenarlos
con valores u ordenar sus elementos. Java proporciona la clase Arrays, la cual contiene varios
metodos utiles para manipular arreglos. El cuadro 2 muestra algunos de los metodos mas utiles de
la clase Arrays. Para cada metodo de la columna izquierda de la tabla, tipo es para un tipo de
dato; una version sobrecargada que existe de cada metodo para cada tipo de dato apropiado. Por

11
Metodo Proposito
static int binarySearch(tipo[] a, tipo llave) Busca en el arreglo indicado el
valor dado por la llave usando
busqueda binaria. Se requiere que
el arreglo este ordenado en forma
creciente.
static boolean equals(tipo[] a, tipo[] b) Devuelve true si los dos arreglos
especificados del mismo tipo son
iguales en cantidad de elementos y
elemento a elemento en la misma
posicion.
static void fill(tipo[] a, tipo val) Asigna el valor indicado a cada ele-
mento del arreglo indicado.
static void sort(tipo[] a) Ordena el arreglo indicado en or-
den ascendente.
static void sort(tipo[] a, int inicial, int final) Ordena el rango, definido por los
subndices inicial a final, del arre-
glo indicado en orden ascendente.

Cuadro 2: metodos utiles de la clase Arrays.

ejemplo, hay una version del metodo sort() para ordenar arreglos de int, double, char, byte,
float, long, short y Object.

Los metodos en la clase Arrays son metodos static, por lo que se usan con el nombre de la clase
sin instanciar un objeto Arrays. La clase Arrays esta localizada en el paquete java.util, as que
se puede usar la sentencia import java.util.* para accederla. La aplicacion DemoArrays, codigo
4, muestra como se pueden usar algunos metodos de la clase Arrays. En la clase DemoArrays,
el arreglo puntuaciones es creado para guardar cinco enteros. Luego, un mensaje y la referencia
arreglo son pasados al metodo mostrar(). Al ejecutar la aplicacion se debe mostrar el arreglo
original creado llenado con ceros. Despues se llama al metodo Arrays.fill() con el nombre del
arreglo y el numero 7, para luego mostrar el arreglo por segunda vez mostrando siete. Luego dos
elementos, el segundo y el ultimo, son cambiados a 3 y 8 respectivamente, y el arreglo se muestra
nuevamente. Despues se llama al metodo Arrays.sort() para ordenar en forma ascendente el
arreglo y se vuelve a mostrar el arreglo por cuarta ocasion.

12
1 import j a v a . u t i l . Arrays ;
2 public c l a s s DemoArrays {
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 [ 5 ] ;
5 mostrar ( Arreglo o r i g i n a l : , puntuaciones ) ;
6 Arrays . f i l l ( p u n t u a c i o n e s , 7 ) ;
7 mostrar ( Luego de l l e n a r con 7 : , p u n t u a c i o n e s ) ;
8 puntuaciones [ 1 ] = 3;
9 puntuaciones [ 4 ] = 8;
10 m o s t r a r ( Luego de cambiar dos v a l o r e s : , p u n t u a c i o n e s ) ;
11 Arrays . s o r t ( p u n t u a c i o n e s ) ;
12 mostrar ( Luego de o r d e n a r : , p u n t u a c i o n e s ) ;
13 }
14 public s t a t i c void m o s t r a r ( S t r i n g mensaje , int [ ] a r r e g l o ) {
15 int tam = a r r e g l o . l e n g t h ;
16 System . out . p r i n t ( mensaje ) ;
17 f o r ( int v a l o r : a r r e g l o )
18 System . out . p r i n t ( v a l o r + ) ;
19 System . out . p r i n t l n ( ) ;
20 }
21 }

Codigo 4: Aplicacion DemoArrays.

Los metodos binarySearch() de la clase Arrays son una manera conveniente para buscar en listas
ordenadas de valores de diferentes tipos de datos. La lista debera estar en orden ascendente para
usar el metodo binarySearch(). La forma como trabaja la busqueda binaria usada por el metodo
binarySearch() es como sigue.

Se encuentra la posicion central usando el tamano del arreglo. Si un arreglo tiene una cantidad
par de elementos, esta puede ser cualquiera de las dos posiciones centrales.

Se compara el dato que se esta buscando con el elemento en la posicion central del arreglo y
se revisa si el valor del dato es menor que el valor de la posicion central.

Si el dato esta por encima de la posicion central, se encuentra la posicion central de la


mitad superior del arreglo; otro caso se encuentra la posicion central de la mitad inferior.
En cualquier caso, se compara el dato con la nueva posicion central y se divide el area de
busqueda en la mitad nuevamente.

Finalmente, se encuentra el valor o se determina que no esta en el arreglo.

Nota. Los programadores frecuentemente se refieren a la busqueda binaria como un procedimiento


divide y veceras. Si se ha jugado en alguna ocasion el juego en cual se trata de adivinar que numero
alguien penso, se podra haber usado una tecnica similar.

Suponer ahora una organizacion que usa seis codigos de una letra para productos. El codigo 5
contiene la aplicacion VerificarCodigo que revisa un codigo de producto dado por el usuario. El
arreglo codigos guarda seis valores en orden ascendente. El usuario ingresa un codigo que es obte-
nido de la primera posicion del String usando el metodo charAt(). Luego, el arreglo de caracteres

13
validos y el caracter ingresado por el usuario son pasados al metodo Arrays.binarySearch(). Si
el caracter es encontrado en el arreglo, su posicion es regresada. si el caracter no es encontrado en
el arreglo, un entero negativo es devuelto y la aplicacion muestra un mensaje de error.

Nota. El entero negativo devuelto por el metodo binarySearch() cuando el valor no es encontrado
es el equivalente negativo del tamano del arreglo. En muchas aplicaciones, no se emplea el valor
devuelto cuando no hay apareamiento, solo se considera si es negativo.

1 import j a v a . u t i l . Arrays ;
2 import j a v a x . swing . JOptionPane ;
3 public c l a s s V e r i f i c a r C o d i g o {
4 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
5 char [ ] c o d i g o s = { B , E , K , M , P , T } ;
6 S t r i n g entrada , mensaje ;
7 char c o d i g o U s u a r i o ;
8 int p o s i c i o n ;
9 e n t r a d a = JOptionPane . sh ow In put Di al og ( null ,
10 I n g r e s a r un co d i g o de p r o d u c t o ) ;
11 c o d i g o U s u a r i o = e n t r a d a . charAt ( 0 ) ;
12 p o s i c i o n = Arrays . b i n a r y S e a r c h ( c o d i g o s , c o d i g o U s u a r i o ) ;
13 i f ( p o s i c i o n >= 0 )
14 mensaje = La p o s i c i on de + c o d i g o U s u a r i o + e s +
15 posicion ;
16 else
17 mensaje = c o d i g o U s u a r i o + e s un co d i g o i n v a l i d o ;
18 JOptionPane . showMessageDialog ( null , mensaje ) ;
19 }
20 }

Codigo 5: La aplicacion VerificarCodigo.

Nota. Los metodos sort() y binarySearch() en la clase Arrays son utiles y permiten lograr
resultados escribiendo menos instrucciones en vez de tener que escribir los metodos propios. Esto
no significa una perdida de tiempo de lectura acerca de los metodos de ordenar y buscar vistos
previamente. Entre mas completo sea el entedimiento de como los arreglos son manipulados, las
futuras aplicaciones seran mas utiles, eficientes y creativas.

Actividad 5. Disenar una aplicacion que permita introducir arbitrariamente hasta 20 nombres en
un arreglo, despues usando el metodo de busqueda binaria localizar la posicion donde se encuentra
ese nombre. No olvidar que antes de intentar usar la busqueda binaria se debe ordenar el arreglo y
solo debera hacerlo en la porcion donde estan los nombres. El usuario puede introducir menos de
20 nombres.

4. Clase ArrayList

La clase ArrayList puede ser usada para crear contenedores que guarden listas de objetos. Es-
ta clase proporciona algunas ventajas sobre la clase Arrays, una de ellas es redimensionable

14
dinamicamente, es decir, que su tamano puede cambiar durante la ejecucion del programa, esto
significa que:

Se puede agregar un elemento en cualquier punto de un contenedor ArrayList, y el tamano


del arreglo se expande automaticamente para acomodar el nuevo elemento.

Se puede quitar un elemento en cualquier punto de un contenedor ArrayList, y el tamano


del arreglo se contrae automaticamente.

Para usar la clase ArrayList se debe usar alguna de las dos sentencias de importacion:

import java.util.ArrayList;
import java.util.*;

Luego, para declarar un ArrayList, se puede usar el constructor por defecto, como se muestra en
el siguiente ejemplo:

ArrayList nombres = new ArrayList();

El constructor por defecto crea un ArrayList con una capacidad de 10 elementos. La capacidad
del ArrayList es la cantidad de elementos que puede guardar sin tener que incrementar su tamano.
Por definicion, la capacidad del ArrayList es mayor que o igual a su tamano. Se puede tambien
indicar una capacidad, como en la siguiente sentencia que declara un ArrayList que puede guarda
20 nombres:

ArrayList nombres = new ArrayList(20);

Si se sabe que se necesitaran mas de 10 elementos desde el principio, es mas eficiente crear un
ArrayList con una capacidad mayor que la asignada por el constructor.

El cuadro 3 resume algunos de los metodos mas utiles del ArrayList.

Metodo Proposito
public void add(Object) Agrega un elemento en la siguiente localidad dis-
ponible.
public void add(int, Object) Agrega un elemento en la localidad especificada.
public void remove(int) Quita un elemento en la localidad indicada.
public void set(int, Object) Modifica con Object un elemento en la localidad
especificada.
public Object get(int) Devuelve el elemento de la localidad indicada.
public int size() Regresa el tamano.

Cuadro 3: Metodos utiles de la clase ArrayList.

Nota. La clase Object es la clase de Java mas generica, esta clase es la raz de todas las clases.

15
Para agregar un elemento al final de un ArrayList se usa el metodo add. Suponer que se quiere
agregar el nombre Javier al ArrayList llamado nombres, entonces usar la siguiente sentencia:

nombres.add("Javier");

Se puede insertar un elemento en una posicion especfica en un ArrayList usando una version
sobrecargada del metodo add() que incluye la posicion. Para insertar el nombre Juana en la
primera posicion del ArrayList nombres, usar la siguiente sentencia:

nombres.add(0, "Juana");

Con algunos de los metodos descritos en la tabla 3, se recibe un mensaje de error si la posicion es
invalida para el ArrayList. Tambien estan disponibles metodos para modificar y quitar elementos
de un ArrayList. Con el metodo size() se puede saber la cantidad de elementos que tiene un
ArrayList, no confundir con la capacidad del ArrayList.

En la aplicacion DemoArrayList, codigo 6, se muestran algunos de los metodos mencionados.

1 import j a v a . u t i l . A r r a y L i s t ;
2 public c l a s s DemoArrayList {
3 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
4 A r r a y L i s t nombres = new A r r a y L i s t ( ) ;
5 nombres . add ( Aixa ) ; // a g r e g a r a l f i n a l
6 m o s t r a r ( nombres ) ;
7 nombres . add ( A l e j a n d r o ) ; // a g r e g a r a l f i n a l d r a w b a c k
8 m o s t r a r ( nombres ) ;
9 nombres . add ( Ana Karen ) ; // a g r e g a r a l f i n a l
10 m o s t r a r ( nombres ) ;
11 nombres . add ( 2 , Benjamin ) ; // a g r e g a r en l a 3a p o s i c i on
12 m o s t r a r ( nombres ) ;
13 nombres . remove ( 1 ) ; // q u i t a r e l segundo nombre
14 m o s t r a r ( nombres ) ;
15 nombres . s e t ( 0 , C a r l o s ) ; // m o d i f i c a r l a primera p o s i c i on
16 m o s t r a r ( nombres ) ;
17 }
18 public s t a t i c void m o s t r a r ( A r r a y L i s t nombres ) {
19 System . out . p r i n t l n ( \ nEl tamano de l a l i s t a e s +
20 nombres . s i z e ( ) ) ;
21 f o r ( int i =0; i <nombres . s i z e ( ) ; ++i )
22 System . out . p r i n t l n ( p o s i c i on + ( i +1) + Nombre : +
23 nombres . g e t ( i ) ) ;
24 }
25 }

Codigo 6: Aplicacion DemoArrayList.

En la aplicacion DemoArrayList, codigo 6, se crea un ArrayList y luego se agrega Aixa. En-


seguida el ArrayList es pasado al metodo mostrar() para desplegar el tamano actual de esta y
todos los nombres en la lista. Ejecutar la aplicacion DemoArrayList para observar la salida de la
aplicacion indicando un tamano de 1 y mostrando un solo nombre. Revisando simultaneamente

16
el codigo 6 y la salida de la aplicacion se puede entender como el ?? es modificado conforme los
nombres son agregados, quitados, y reemplazados.

Se puede mostrar los contenidos de un ArrayList de String sin iterar a traves de los valores.
En la aplicacion DemoArrayList2, codigo 7, se muestra un ArrayList llamado estudiantes que
el usuario llena interactivamente. Se muestra el arreglo de nombres como una lista separada con
comas y encerrada entre corchetes, al concatenar un String con el ArrayList en la lnea .

1 import j a v a . u t i l . A r r a y L i s t ;
2 import j a v a x . swing . JOptionPane ;
3 public c l a s s DemoArrayList2 {
4 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
5 A r r a y L i s t e s t u d i a n t e s = new A r r a y L i s t ( ) ;
6 S t r i n g nombre ;
7 f i n a l int LIMITE = 4 ;
8 f o r ( int i =0; i <LIMITE ; ++i ) {
9 nombre = JOptionPane . sh ow In put Di al og ( null ,
10 I n g r e s a r e l nombre d e l e s t u d i a n t e ) ;
11 e s t u d i a n t e s . add ( nombre ) ;
12 }
13 System . out . p r i n t l n ( Los nombres son : + e s t u d i a n t e s ) ;
14 }
15 }

Codigo 7: Aplicacion DemoArrayList2

Nota. Se pueden lograr resultados similares usando un ArrayList con cualquier tipo de clase.
Recordar que cada clase contiene un metodo toString() que convierte su objeto a un String; este
metodo es usado cuando se muestra el ArrayList. Para que la cadena devuelta por toString()
sea util es necesario invalidarlo con una implementacion propia.

Se puede ordenar un ArrayList usando el metodo Collections.sort() y dando el ArrayList


como el argumento, por ejemplo:

Collections.sort(estudiantes);

Para usar este metodo, se debe importar el paquete java.util.Collections al inicio del archivo.

Actividad 6. Usar el metodo Collections.sort() para ordenar el ArrayList de la aplicacion


DemoArrayList2, codigo 7, antes de mostrar la coleccion de nombres.

Limitaciones de la clase ArrayList

Un ArrayList puede ser usado para guardar cualquier tipo de referencia de objeto. De hecho, un
ArrayList puede guardar tipos multiples. Sin embargo, esto genera dos inconvenientes:

No se puede usar un ArrayList para guardar tipos primitivos, como int o char, porque no
son referencias. Si se quiere trabajar con tipos primitivos, se puede crear un arreglo o usar la
clase Arrays.

17
Cuando se quiere guardar elementos ArrayList, se deben convertir al tipo de referencia apro-
piada antes de guardar, o se debe declarar un tipo de referencia en la declaracion ArrayList.

Por ejemplo, si se quiere declarar un String para guardar el primer nombre en el ArrayList
nombres, se deberan hacer sentencias tales como las siguientes:

String primerNombre;
primerNombre = (String)nombres.get(0);

El operador de moldeo (String) convierte el objeto generico devuelto por el metodo get() a un
String. Si no se realiza esta conversion, se recibe un mensaje de error indicando que ese estan
usando tipos incompatibles.

Se puede eliminar la necesidad de realizar una conversion con objetos ArrayList indicando el tipo
que un ArrayList puede guardar. Por ejemplo, se puede declarar un ArrayList de nombres as:

ArrayList<String> nombres = new ArrayList<String>();

Cuando se crea una declaracion ArrayList con un tipo especificado proporciona varias ventajas:

No se puede usar mas el operador de conversion cuando se recupere un elemento del ArrayList.

Java revisa para asegurarse que solo elementos del tipo apropiado son usados en la lista.

La advertencia del compiladorn que indica que el programa usa una operacion no revisada o
insegura es eliminada.

Actividad 7. Modificar la aplicacion DemoArrayList2, codigo 7, para que en el ArrayList estu-


diantes se indique que guardara el tipo String.

5. Enumeraciones

Se pueden crear tipos de datos propios que tengan un conjunto finito de valores validos. Un tipo de
dato creado por el programador con un conjunto fijo de valores es un tipo de dato enumerado.

Para crear en Java un tipo de dato enumerado se debe usar la palabra reservada enum, un identi-
ficador para el tipo, y un juego de llaves que contenga la lista de las constantes enum, las cuales
son los valores permitidas para el tipo. El siguiente codigo crea un tipo enumerado llamado Mes
que contiene doce valores:

enum Mes {ENE, FEB, MAR, ABR, MAY, JUN,


JUL, AGO, SEP, OCT, NOV, DIC};

18
Por convencion, el identificador para el tipo enumerado inicia con una letra mayuscula. Esta conven-
cion tiene sentido porque un tipo enumerado es una clase. Tambien, por convencion, la constantes
enum, como otras constantes, se ponen todas las letras en mayusculas. Las constantes no son cadenas
y por lo tanto no se encierran entre comillas; son como identificadores Java.

Despues de crear un tipo de dato enumerado, se puede declarar variables de ese tipo. Por ejemplo,
se podra declarar lo siguiente:

Mes mesNacimiento;

Se puede asignar cualquiera de las constantes enum a la variable. Entonces se puede codificar una
sentencia como la siguiente:

mesNacimiento = Mes.MAY;

Un tipo enumeracion como Mes es una clase, y sus constantes enum trabajan como objetos instan-
ciadas de la clase, incluyendo el tener acceso a los metodos de la clase. Estos metodos integrados,
incluyendo los que se muestran en el cuadro 4, son no estaticos, por lo que deben ser usados con
un objeto enum.

Ejemplo con
Metodo Descripcion mesNacimiento = Mes.MAY;
toString() Regresa el nombre del objeto cons- mesNacimiento.toString() tiene
tante llamado el valor MAY. Cuando se pa-
sa mesNacimiento a print() o
println() es convertido automati-
camente a su cadena equivalente.
ordinal() Devuelve un entero que representa la mesNacimiento.ordinal() es cua-
posicion de la constante en la lista tro.
de constantes. La primera posicion es
cero.
equals() Devuelve true si su argumento es mesNacimiento.equasl(Mes.MAY)
igual al valor del objeto que llama. es true.
mesNacimiento.equasl(Mes.DIC)
es false.
compareTo() Regresa un entero negativo si el valor mesNacimiento.compareTo(Mes.AGO)
ordinal del objeto que llama es menor es negativo.
que el argumento, cero si son iguales, mesNacimiento.compareTo(Mes.ENE)
y un entero positivo si el valor ordinal es positivo.
es mayor que el del argumento mesNacimiento.compareTo(Mes.MAY)
es cero.

Cuadro 4: Algunos metodos enum no estaticos

Tambien hay varios metodos estaticos disponibles para ser usados con enumeraciones. Estos son
usados con el tipo y no con constantes individuales. La tabla 5 describe dos metodos utiles de este
tipo.

19
Metodo Descripcion Ejemplo con enumeracion Mes
valueOf() El metodo acepta un parametro Month.valueOf("SEP") regresa la
String y regresa una enumeracion constante enum SEP.
constante.
values() El metodo regresa un arreglo de las Mes.values() regresa un arreglo
constantes enumeradas. con doce elementos que contiene
las constantes enum.

Cuadro 5: Algunos metodos estaticos enum

Se puede declarar un tipo enumerado en su propio archivo, en tal caso el nombre del archivo
empata el nombre del tipo y tiene extension .java. Tambien se puede declarar un tipo enumerado
dentro de una clase pero no dentro de un metodo. En la aplicacion DemoEnum, codigo 8, declara una
enumeracion Mes y muestra su uso.

1 import j a v a . u t i l . Scanner ;
2 public c l a s s DemoEnum {
3 enum Mes {ENE, FEB, MAR, ABR, MAY, JUN,
4 JUL , AGO, SEP , OCT, NOV, DIC } ;
5
6 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
7 Mes mesNacimiento ;
8 String entrada ;
9 int p o s i c i o n ;
10 int comparacion ;
11 Scanner t e c l a d o = new Scanner ( System . i n ) ;
12 System . out . p r i n t l n ( Los meses son : ) ;
13 f o r ( Mes mes : Mes . v a l u e s ( ) )
14 System . out . p r i n t ( mes + ) ;
15 System . out . p r i n t ( \n\ n I n g r e s a r l a s p r i m e r a s t r e s l e t r a s de +
16 su mes de n a c i m i e n t o >> ) ;
17 e n t r a d a = t e c l a d o . n e x t L i n e ( ) . toUpperCase ( ) ;
18 mesNacimiento = Mes . v a l u e O f ( e n t r a d a ) ;
19 System . out . p r i n t l n ( Ha i n g r e s a d o + mesNacimiento ) ;
20 p o s i c i o n = mesNacimiento . o r d i n a l ( ) ;
21 System . out . p r i n t l n ( mesNacimiento + e s t a en l a p o s i c i on + p o s i c i o n ) ;
22 System . out . p r i n t l n ( As e l numero de mes e s + ( p o s i c i o n + 1 ) ) ;
23 comparacion = mesNacimiento . compareTo ( Mes . JUN ) ;
24 i f ( comparacion < 0 )
25 System . out . p r i n t l n ( mesNacimiento +
26 e s t a a n t e s en e l ano que + Mes . JUN ) ;
27 else
28 i f ( comparacion > 0 )
29 System . out . p r i n t l n ( mesNacimiento +
30 e s t a despue s en e l ano que + Mes . JUN ) ;
31 else
32 System . out . p r i n t l n ( mesNacimiento + e s + Mes . JUN ) ;
33 }
34 }

Codigo 8: La aplicacion DemoEnum.

20
En la aplicacion, codigo 8, una enumeracion Mes es declarada en el metodo main(), una variable
Mes es declarada en la lnea 7. En la lnea 13 la sentencia usa el ciclo for avanzado, el cual declara
una variable local Mes llamada mes que toma el valor de cada elemento del arreglo devuelto por
Mes.values() para mostrarlo. Luego en la aplicacion se pide que se ingresen las primeras tres
letras de un mes, que son convertidas a mayusculas. En la lnea 18 se usa el metodo valueOf()
para convertir la cadena del usuario a un valor enumerado. En la lnea 20 se obtiene la posicion del
mes en la lista de enumeracion. En la lnea 23 se compara el mes ingresado con la constante JUN.
Despues se tiene una sentencia if que muestra si el mes ingresado esta antes o despues de JUN en
la lista, o si es igual.

Comenzando con Java 7, se pueden usar operadores de comparacion con constantes enumeradas
en vez de usar el metodo compareTo() para devolver un numero. El siguiente ejemplo muestra lo
comentado:

if (mesNacimiento < Mes.JUN)


System.out.println(mesNacimiento +
" esta antes en el a~
no que " + Mes.JUN);

Se pueden usar enumeraciones para controlar una estructura switch. La aplicacion DemoEnum2,
codigo 9, declara una enumeracion Propiedad para una empresa de bienes races. La aplicacion
asigna uno de los valores a una variable Propiedad y luego usa una estructura switch para mostrar
un mensaje. Ejecutar esta aplicacion para revisar lo senalado.

1 import j a v a . u t i l . Scanner ;
2 public c l a s s DemoEnum2 {
3 enum Propiedad {FAMILIA SOLA , FAMILIA MULTIPLE ,
4 CONDOMINIO, TERRENO, NEGOCIO} ;
5 public s t a t i c void main ( S t r i n g [ ] a r g s ) {
6 Propiedad propiedadEnVenta = Propiedad . FAMILIA MULTIPLE ;
7 switch ( propiedadEnVenta ) {
8 case FAMILIA SOLA :
9 case FAMILIA MULTIPLE :
10 System . out . p r i n t l n ( H o n o r a r i o s 5 % ) ;
11 break ;
12 case CONDOMINIO:
13 System . out . p r i n t l n ( H o n o r a r i o s 6 % ) ;
14 break ;
15 case TERRENO:
16 case NEGOCIO:
17 System . out . p r i n t l n (
18 No manejamos e s t e t i p o de p r o p i e d a d ) ;
19 }
20 }
21 }

Codigo 9: Aplicacion DemoEnum2.

Se tienen varias ventajas creando un tipo enumeracion. Para el caso de la enumeracion Mes mejora
los programas en las siguientes formas:

1. Si no se crea un tipo enumerado para los valores del mes, se podra crear otro tipo, como

21
int o String. El problema es que cualquier valor podra ser asignado a una variable int o
String, pero a Mes solo se pueden asignar los doce valores permitidos.

2. Se podra tener un comportamiento sin sentido con los valores si no se crea un tipo enumerado
para los valores del mes. Por ejemplo, si se usaron enteros para representar meses, se podra
agregar, sustraer, multiplicar o dividir dos meses, lo cual no es logico. Los programadores
dicen que usando enum hace los valores tipo seguro. Tipo seguro describe un tipo de dato
para el cual solo comportamientos apropiados son permitidos.

3. Las constantes enum proporcionan una forma de autodocumentacion. Alguien leyendo el pro-
grama podra malinterpretar el significado de 6 como valor de mes, pero hay menos confusion
cuando se usa el identificador JUN.

4. Al igual que con otras clases, se puede tambien agregar metodos y otros campos a un tipo
enum.

Actividad 8. Crear una aplicacion que cree dos objetos tipo Auto y los muestre. La clase Auto
tendra tres campos, el ano, el tipo de auto y el color; esta clase tambien tendra un metodo que
muestre la informacion de los tres campos. La clase Auto use dos enumeraciones, una para el color
del auto y otra para el tipo de auto (SEDAN, CONVERTIBLE, MINIVAN). Cada enumeracion
debera estar en su propio archivo Java.

22

You might also like