N3: MANEJO DE GRUPOS DE ATRIBUTOS
Nychol Bazurto Gómez

Contenedoras de tamaño fijo
Nivel
3
Instrucciones repetitivas
Contenedoras de tamaño variable
Uso de ciclos
Creación de una clase
Qué vamos a aprender
- Estructuras contenedoras, que nos permiten manejar atributos cuyo valor corresponde a una secuencia de elementos.
- Instrucciones repetitivas, que son instrucciones que nos permiten manipular los elementos contenidos en dichas secuencias.
- Recorridos
- Totales
- Parciales
- Dobles
- Crear una clase completa en java utilizando eclipse.
Caso de estudio No. 1: EL REFUGIO de perros
- En el refugio hay 10 perros
- De cada perro se tiene la edad (un valor entre 0.0 y 14.0)
Se quiere construir un programa que permita:
1. Cambiar la edad de un perro.
2. Calcular el promedio de edad del refugio
3. Establecer el número de perros que están por encima de dicho promedio.

EL REFUGIO DE PERROS

R1: Cambiar
Resumen: Permite cambiar la edad de un perro del refugio.
Entradas
1. El perro a quien se quiere cambiar la edad
2. La nueva edad del perro
Se ha
Resultado
EL REFUGIO DE PERROS

R2: Calcular el promedio
Resumen: Permite calcular la edad promedio de los perros del refugio.
Entradas
Ninguna
El promedio de las edades de los diez perros del refugio.
Resultado
EL REFUGIO DE PERROS

R3: Calcular el número de perros por encima del promedio.
Resumen: Permite saber cuántos perros tienen una edad superior a la edad promedio del refugio.
Entradas
Ninguna
Número de perros con edad mayor al promedio del erfugio
Resultado
MODELO

| Refugio |
|---|
| double edad1; double edad2; double edad3; double edad4; double edad5; double edad6; double edad7; double edad8; double edad9; double edad10; |

USANDO CONTENEDORES

| Refugio |
|---|
| double edad1; double edad2; double edad3; double edad4; double edad5; double edad6; double edad7; double edad8; double edad9; double edad10; |
| Refugio |
|---|
| double[] edades = |
| 0 | |
|---|---|
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 |
Un solo
ARREGLO = CONTENEDORA DE TAMAño fijo

| 5 | 6.7 | 2 | 3.5 | 10 | 7 | 8 | 1.2 | 1 | 0 |
|---|
edades[0]
edades[4]
edades[8]
0
1
2
3
4
5
6
7
8
9
Cada posición del arreglo (casilla) se utiliza como una variable
edades[5] = 3.0;
i = 2;
if ( edades[ i ] > 4.0)
edades[7] = edades[3];
if (edades[6] == edades[0])
edades[0] = 2.0;
else
edades[0] = edades[9];Contenedoras de tamaño fijo
- Definir que van a “contener”: int, double, String, char, boolean u objetos.
-
Una vez definido el tipo se pueden declarar como atributos:
- private <tipo>[] <nombre>;
- Ejemplo: private double[] notas;
- Ejemplo: private Perro[] perros;
-
Se pueden declarar como variables temporales (dentro de métodos), aunque no es algo usual:
- <tipo>[] nombre;
- Ejemplo: double[] notas;
- Ejemplo: Perro[] perros;
Contenedoras de tamaño fijo
-
Para el caso de los perros, suponemos que la clase Perro tiene el siguiente constructor:
- public Perro (String pNombre, double pEstatura)
- La inicialización de los elementos del arreglo perros sería:
-
perros [0] = new Perro(“Kaiser”, 1.23);
perros [1] = new Perro(“Balto”, 0.85);
…
perros[CANT_PERROS-1] = new Perro(…);
ó
perros[perros.length-1] = new Perro(…);
perros = new Perro[ TOTAL_PERROS ] ;
Contenedoras de tamaño fijo
- Si se trata de acceder a una casilla con índice menor que 0 o mayor que el número máximo de casillas (en este caso 10) java.lang.ArrayIndexOutOfBoundsException
INSTRUCCIONES REPETITIVAS
Una solución puede lograrse repitiendo un paso que vaya transformando gradualmente el estado del mundo modelado
CALCULAR EL PROMEDIO DE EDADES
1. Sumar todas las edades.
2. Dividir por el número de perros.
public double promedio( )
{
double suma = perros[ 0 ] + perros[ 1 ] + perros[ 2 ] +
perros[ 3 ] + perros[ 4 ] + perros[ 5 ] +
perros[ 6 ] + perros[ 7 ] + perros[ 8 ] +
perros[ 9 ] + perros[ 10 ] + perros[ 11 ];
return suma / TOTAL_PERROS;
}
CALCULAR EL PROMEDIO DE EDADES
public double promedio( )
{
double suma = 0.0;
int indice = 0;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
indice++;
suma += perros[ indice ];
return suma / TOTAL_PERROS;
}Utiliza un índice que va desplazando desde 0 hasta 11
Paso
CALCULAR EL PROMEDIO DE EDADES
public double darPromedio( )
{
double suma = 0.0;
int indice = 0;
while( indice < TOTAL_PERROS )
{
suma += perros[ indice ];
indice++;
}
return suma / TOTAL_PERROS;
}se encarga de ejecutar repetidamente las instrucciones que tiene en su interior
"mientras que" una condición se cumpla, siga ejecutando las instrucciones que están por dentro.
"mientras que" el índice no llegue a 12, vuelva a ejecutar la pareja de instrucciones que tiene asociadas.
Componentes de una Instrucción Repetitiva
Preparación del
¿La condición es
SI
NO
termina el ciclo
Ejecuta las instrucciones del cuerpo del ciclo
Componentes de una Instrucción Repetitiva
Preparación del
¿La condición es
SI
NO
termina el ciclo
Ejecuta las instrucciones del cuerpo del ciclo
public double darPromedio( )
{
double suma = 0.0;
int indice = 0;
while( indice < TOTAL_PERROS )
{
suma += perros[ indice ];
indice++;
}
return suma / TOTAL_PERROS;
}Las Instrucciones WHILE y FOR
<inicio>
while( <condición> )
{
<cuerpo>
<avance>
}for (<inicio>; <condición>; <avance>)
{
<cuerpo>
}Las Instrucciones WHILE y FOR
public double darPromedio( )
{
double suma = 0.0;
int indice = 0;
while( indice < TOTAL_PERROS )
{
suma += perros[ indice ];
indice++;
}
return suma / TOTAL_PERROS;
}Inicio de las variables de trabajo:
• Indice para movernos en el arreglo.
• Acumulado de la suma de las edades.
Las Instrucciones WHILE y FOR
public double darPromedio( )
{
double suma = 0.0;
int indice = 0;
while( indice < TOTAL_PERROS )
{
suma += perros[ indice ];
indice++;
}
return suma / TOTAL_PERROS;
}
Condición para continuar:
• Cualquier expresión lógica
Las Instrucciones WHILE y FOR
public double darPromedio( )
{
double suma = 0.0;
int indice = 0;
while( indice < TOTAL_PERROS )
{
suma += perros[ indice ];
indice++;
}
return suma / TOTAL_PERROS;
}
Cuerpo del ciclo:
• Instrucciones que se van a repetir en cada iteración
Las Instrucciones WHILE y FOR
public double darPromedio( )
{
double suma = 0.0;
int indice = 0;
while( indice < TOTAL_PERROS )
{
suma += perros[ indice ];
indice++;
}
return suma / TOTAL_PERROS;
}
Avance del ciclo:
• Incremento del índice que indica la posición del arreglo en la que estamos en un momento dado
Las Instrucciones WHILE y FOR
public double darPromedio( )
{
double suma = 0.0;
for ( int indice = 0; indice < TOTAL_PERROS; indice ++ )
{
suma += perros[ indice ];
}
suma = suma / TOTAL_PERROS;
return suma;
}Inicio de las variables de trabajo:
• Indice para movernos en el arreglo.
• Acumulado de la suma de las edades.
Las Instrucciones WHILE y FOR
public double darPromedio( )
{
double suma = 0.0;
for ( int indice = 0; indice < TOTAL_PERROS; indice ++ )
{
suma += perros[ indice ];
}
suma = suma / TOTAL_PERROS;
return suma;
}
Condición para continuar:
• Cualquier expresión lógica
Las Instrucciones WHILE y FOR
public double darPromedio( )
{
double suma = 0.0;
for ( int indice = 0; indice < TOTAL_PERROS; indice ++ )
{
suma += perros[ indice ];
}
suma = suma / TOTAL_PERROS;
return suma;
}
Cuerpo del ciclo:
• Instrucciones que se van a repetir en cada iteración
Las Instrucciones WHILE y FOR
public double darPromedio( )
{
double suma = 0.0;
for ( int indice = 0; indice < TOTAL_PERROS; indice ++ )
{
suma += perros[ indice ];
}
suma = suma / TOTAL_PERROS;
return suma;
}
Avance del ciclo:
• Incremento del índice que indica la posición del arreglo en la que estamos en un momento dado
PRACTIQUEMOS
Calcular el número de perros que tienen una edad entre 2 y 8.
public int cuantosTienenEdadEnRango ( )
{
...
}Calcular la mayor
public int mayorEdad ( )
{
...
}Contar el número de perros que tienen una edad inferior a la del perro que está en la posición del arreglo que llega como parámetro. Suponga que el parámetro posPerro tiene un valor entre 0 y TOTAL_PERROS-1
public int cuantosMenoresQue ( int posEst )
{
...
}Incrementar todas las edades de los perros en 1.
public void incrementarEdad ( ) {
...
}PATRONES DE ALGORITMO PARA INSTRUCCIONES REPETITIVAS
Un patrón de algoritmo se puede ver como una solución genérica para un tipo de problemas, en la cual el programador sólo debe resolver los detalles particulares de su problema específico.
-
Patrón de Recorrido Total
-
Patrón de Recorrido Parcial
-
Patrón de Doble Recorrido
PATRÓN DE RECORRIDO TOTAL
¿Cuándo
Se necesita recorrer TODO el arreglo y además ACUMULAR o CALCULAR alguna propiedad sobre TODOS los elementos.
- Calcular la
suma detodas lasedades . - Contar cuántos perritos tienen más de 9 años.
- Contar cuántos están por debajo del promedio de edad.
Ejemplos
- El índice para iniciar el ciclo debe empezar en cero.
- La condición para continuar es que el índice sea menor que la longitud del arreglo.
- El avance consiste en sumarle uno al índice.
PATRÓN DE RECORRIDO TOTAL
for( int indice = 0; indice < arreglo.length; indice++ )
{
<cuerpo>
}
Indice para movernos en el arreglo empieza en CERO
Condición para continuar: índice menor que la longitud del arreglo
Avance:
PATRÓN DE RECORRIDO TOTAL
¿Cuándo
Se necesita recorrer TODO el arreglo y además ACUMULAR o CALCULAR alguna propiedad sobre TODOS los elementos.
Decisiones a tomar:
– ¿Cómo acumular?
– ¿Cómo inicializar el acumulado?
– ¿Condición para cambiar el acumulado?
– ¿Cómo cambiar el acumulado?
PATRÓN DE RECORRIDO TOTAL
¿Cuándo
Se necesita recorrer TODO el arreglo y además ACUMULAR o CALCULAR alguna propiedad sobre TODOS los elementos.
public int darCantidadPerrosAdultos( )
{
int vanAdultos = 0;
for( int i = 0; i < perros.length; i++ )
{
if( perros[ i ] >= 2.0 )
{
vanAdultos++;
}
}
return vanAdultos;
}¿Cómo
Con
PATRÓN DE RECORRIDO TOTAL
¿Cuándo
Se necesita recorrer TODO el arreglo y además ACUMULAR o CALCULAR alguna propiedad sobre TODOS los elementos.
public int darCantidadPerrosAdultos( )
{
int vanAdultos = 0;
for( int i = 0; i < perros.length; i++ )
{
if( perros[ i ] >= 2.0 )
{
vanAdultos++;
}
}
return vanAdultos;
}¿Cómo inicializar el acumulado?
En cero o en un valor adaptado al problema
PATRÓN DE RECORRIDO TOTAL
¿Cuándo
Se necesita recorrer TODO el arreglo y además ACUMULAR o CALCULAR alguna propiedad sobre TODOS los elementos.
public int darCantidadPerrosAdultos( )
{
int vanAdultos = 0;
for( int i = 0; i < perros.length; i++ )
{
if( perros[ i ] >= 2.0 )
{
vanAdultos++;
}
}
return vanAdultos;
}¿Condición para cambiar el acumulado?
En este ejemplo, cuando el elemento que se está revisando sea mayor o
igual a 2
PATRÓN DE RECORRIDO TOTAL
¿Cuándo
Se necesita recorrer TODO el arreglo y además ACUMULAR o CALCULAR alguna propiedad sobre TODOS los elementos.
public int darCantidadPerrosAdultos( )
{
int vanAdultos = 0;
for( int i = 0; i < perros.length; i++ )
{
if( perros[ i ] >= 2.0 )
{
vanAdultos++;
}
}
return vanAdultos;
}¿Cómo modificar el acumulado?
En este ejemplo, incrementándolo en 1
PATRÓN DE RECORRIDO PARCIAL
¿Cuándo
Se usa cuando NO se necesita recorrer TODO el arreglo
Existe una condición que debemos verificar en cada iteración para saber si debemos detener el ciclo o volver a repetirlo.
Ejemplos
–Decidir si al menos un perro tiene 5 años.
–Buscar el primer perro con edad igual a 1.
- Indicar si más de 3 perros son adultos.
PATRÓN DE RECORRIDO PARCIAL
boolean termino = false;
for( int i = 0; i < arreglo.length && !termino; i++ )
{
<cuerpo>
if( <ya se cumplió el objetivo> )
{
termino = true;
}
}Utilizar una variable auxiliar (centinela) facilita el manejo de la condición a calcular.
PATRÓN DE RECORRIDO PARCIAL
public boolean algunoConCinco ( )
{
boolean termino = false;
for ( int i = 0; i < perros.length && !termino; i++)
{
if ( perros[ i ] == 5.0 )
termino = true;
}
return termino;
}PATRÓN DE RECORRIDO PARCIAL
public boolean alguienConCinco ( )
{
int i = 0;
while ( i < perros.length && perros[ i ] != 5.0 )
{
i++;
}
if ( i == perros.length)
return false;
else
return true;
}PATRÓN DE RECORRIDO PARCIAL CON ACUMULADO
- Se usa cuando NO se necesita recorrer TODO el arreglo, sino hasta que se cumpla una condición y además
•Se necesita ACUMULAR o CALCULAR alguna propiedad sobre los elementos
PATRÓN DE RECORRIDO PARCIAL CON ACUMULADO
public void subirTresEdades( )
{
int numEdades = 0;
boolean termino = false;
for ( int i = 0; i < perros.length && !termino; i++)
{
if ( perros[ i ] == 1.5 )
{
numEdades++;
perros[ i ] = 2.5;
}
if ( numEdades == 3 )
termino = true;
}PATRÓN DE RECORRIDO PARCIAL CON ACUMULADO SIN CENTINELA
public void subirTresEdades( )
{
int numEdades = 0;
for ( int i = 0; i < perros.length && numEdades < 3; i++)
{
if ( perros[ i ] == 1.5 )
{
numEdades++;
perros[ i ] = 2.5;
}
}
}PATRÓN DE RECORRIDO DOBLE
Solución de aquellos problemas en los cuales, por cada elemento de la secuencia, se debe hacer un recorrido completo.
Encontrar la edad que aparece un mayor número de veces en el refugio.
for( int indice1 = 0; indice1 < arreglo.length; indice1++ )
{
for( int indice2 = 0; indice2 < arreglo.length; indice2++ )
{
<cuerpo del ciclo interno>
}
<cuerpo del ciclo externo>
}PATRÓN DE RECORRIDO DOBLE
for( int indice1 = 0; indice1 < arreglo.length; indice1++ )
{
for( int indice2 = 0; indice2 < arreglo.length; indice2++ )
{
<cuerpo del ciclo interno>
}
<cuerpo del ciclo externo>
}- El ciclo de afuera está manejado por la variable indice1.
- El ciclo interno por la variable indice2.
¿Podemos usar dentro del cuerpo del ciclo interno la variable indice1?
patrón de algoritmo de recorrido total con doble recorrido
public double darEdadMasRecurrente( )
{
double edadMasRecurrente = 0.0;
for( int i = 0; i < perros.length; i++ )
{
for( int j = 0; j < perros.length; j++ )
{
//Por completar
}
}
return edadMasRecurrente ;
}patrón de algoritmo de recorrido total con doble recorrido
(1) Contar el número de veces que aparece en el arreglo el valor que está en la casilla i;
(2) encontrar el mayor valor entre los que son calculados por el primer problema.
patrón de algoritmo de recorrido total con doble recorrido
(1) Contar el número de veces que aparece en el arreglo el valor que está en la casilla i;
public double darEdadMasRecurrente( )
{
double edadMasRecurrente = 0.0;
for( int i = 0; i < perros.length; i++ )
{
double edadBuscada = notas[ i ];
int contador = 0;
for( int j = 0; j < perros.length; j++ )
{
if( perros[ j ] == edadBuscada )
{
contador++;
}
}
//Por completar
}
return edadMasRecurrente ;
}(2) encontrar el mayor valor entre los que son calculados por el primer problema.
public double darEdadMasRecurrente( )
{
double edadMasRecurrente = 0.0;
int cantidadOcurrencias= 0;
for( int i = 0; i < perros.length; i++ )
{
double edadBuscada = perros[ i ];
int contador = 0;
for( int j = 0; j < perros.length; j++ )
{
if( perros[ j ] == edadBuscada )
{
contador++;
}
}
if( contador > cantidadOcurrencias)
{
edadMasRecurrente = edadBuscada;
cantidadOcurrencias= contador;
}
}
return edadMasRecurrente ;
}- Debemos identificar los dos problemas que queremos resolver (uno con cada ciclo) y, luego, debemos tratar de resolverlos independientemente, usando los patrones de recorrido total o parcial.
- Si para resolver un problema se necesita un tercer ciclo anidado, debemos escribir métodos separados que ayuden a resolver cada problema individualmente, tal como se plantea en el nivel 4, porque la solución directa es muy compleja y propensa a errores.
Contenedoras de tamaño variable = VECTOR
Necesitamos representar grupos de atributos para los cuales no conocemos su tamaño máximo.
import java.util.*;
public class Ejemplo
{
...
private ArrayList<Tipo> nombre;
}Para implementarlas en Java es necesario utilizar una clase de Java que se llama ArrayList (se encuentra en el paquete java.util)
Contenedoras de tamaño variable = VECTOR
...
nombre = new ArrayList<Tipo>( );
- isEmpty( ): es un método que retorna verdadero si el vector no tiene elementos y falso en caso contrario.
- size( ): es un método que retorna el número de elementos que hay en el vector.
DIFERENCIAS ENTRE ARREGLOS Y VECTORES
- Tamaño fijo
- Permite almacenar elementos de tipo simple (int, float, double) y objetos.
- Para implementarlos en java, existe una sintaxis especial:
- [ ]: para obtener un elemento del arreglo
- length: para conocer la longitud
ARREGLO
VECTOR
- Tamaño variable
- NO permite almacenar elementos de tipo simple (int, float, double), SOLO objetos
- Para implementarlos en java debemos utilizar una clase especial de java (ArrayList).
- Para manipular un vector se utiliza entonces la misma sintaxis que utilizamos para manejar cualquier otra clase (llamado a métodos)
DIFERENCIAS ENTRE ARREGLOS Y VECTORES
| Fijo | Variable | |
|---|---|---|
| Nombre | Arreglos | Vectores |
| En Java | tipo[] | ArrayList<tipo> |
| Conocer el tamaño | .length | .size() |
| Obtener | arreglo[0] | .get(posicion); |
| Actualizar | Asigna un valor al elemento por posición. | .set( posicion , elemento); |
| Agregar | Asigna un elemento por posición. | .add(elemento); |
| Eliminar | Asigna null al elemento que se quiere eliminar. | .remove(posicion); |
ASOCIACIONES OPCIONALEs

CASO DE ESTUDIO: PARQUEADERO
Se quiere construir una aplicación para administrar un parqueadero (lugar de estacionamiento para carros). Dicho parqueadero tiene 40 puestos, numerados del 1 al 40.
En cada puesto se puede parquear un sólo carro (que representaremos con una clase llamada Carro), el cual se identifica por su placa. El parqueadero tiene una tarifa por hora o fracción de hora, puede ser cambiada por el administrador.

De cada vehículo aparcado se debe conocer la hora en la que entró, que corresponde a un valor entre 6 y 21, dado que el parqueadero está abierto entre 6 de la mañana y 9 de la noche. Se espera que la aplicación que se quiere construir permita hacer lo siguiente:
CASO DE ESTUDIO: PARQUEADERO
1. Ingresar un carro al parqueadero. Se debe indicar el puesto en el que se debe parquear (si hay cupo).
2. Dar salida a un carro del parqueadero. Se debe indicar cuánto debe pagar.
3. Informar los ingresos del parqueadero.
4. Consultar la cantidad de puestos disponibles.
5. Avanzar una hora en el reloj del parqueadero.
6. Cambiar la tarifa del parqueadero.

CASO DE ESTUDIO: PARQUEADERO

CLASE PARQUEADERO
public class Parqueadero
{
//--------------------------------------------------
// Constantes
//--------------------------------------------------
/**
* Indica el número de puestos en el parqueadero
*/
//--------------------------------------------------
// Atributos
//--------------------------------------------------
/**
* Arreglo de puestos
*/
}public Parqueadero( )
{
}CLASE PARQUEADERO
Escriba el constructor de la clase para inicializar las contenedoras declaradas en el punto anterior.
public int darTotalPuestosOcupados( )
{
}CLASE PARQUEADERO
Contar y retornar el número total de puestos ocupados.
CLASE PARQUEADERO
Informar si en el parqueadero hay un carro cuya placa comience con la letra dada como parámetro.
public boolean existePlacaIniciaCon( char pLetra )
{
}CLASE PARQUEADERO
Retornar el número de carros en el parqueadero que llegaron antes del mediodía.
public int darTotalCarrosIngresoManana( )
{
}CLASE PARQUEADERO
Retornar el último carro en ingresar al parqueadero. Si el parqueadero está vacío, retorna null.
public Carro darCarroLlegadaMasReciente( )
{
}CLASE PARQUEADERO
Informar si hay dos carros en el parqueadero con la misma placa.
public boolean hayPlacasRepetidas( )
{
}¿PREGUNTAS?
¿PREGUNTAS?
Text
GRACIAS
- J. Villalobos and R. Casallas, Fundamentos de Programación. https://cupi2.virtual.uniandes.edu.co/libro-del-curso-pdf/libro-completo
- Iconos hechos por Freepik, Icongeek26 de Flaticon son licenciados por Creative Commons by 3.0
Nivel3
By nychi713
Nivel3
- 696