Вы находитесь на странице: 1из 47

Lenguaje de Programacin Orientado a Objetos Unidad 3. Enumeraciones 3.1 Tipos de datos enumeracin (enum) A partir de la versin de Java SE 5.

0 se pueden definir tipos de datos enumerados (enum) o enumeraciones que constan de diferentes elementos, especifican diversos valores por medio de identificadores y son definidos por el programador mediante la palabra reservada enum; tambin tienen un nmero finito de elementos y valores nombrados; por ejemplo, la siguiente sentencia: enum Notas {A, B, C, D, E}; La sentencia anterior define Notas como un tipo enumerado (enum); los valores de sus elementos son A, B, C, D y E cuyos valores se denominan constantes de enumeracin o enum, se encierran entre llaves ({}) y se separan por comas; las constantes dentro de un tipo enum deben ser nicas; por ejemplo, el tipo de datos DEPORTES: enum DEPORTES {TENIS, ESQU, FUTBOL, BALONCESTO, GOLF}; Define el tipo DEPORTES como enum y sus valores son las constantes similares: TENIS, ESQU, FUTBOL, BALONCESTO y GOLF. Cada enum es un tipo especial de clase y los valores que le pertenecen son objetos de la clase. Despus de definir un tipo de dato enum, se pueden declarar variables con referencia a tal tipo; por ejemplo: DEPORTES miDeporte; y se le puede asignar un valor a la variable: miDeporte=DEPORTES.TENIS; Una variable de tipo DEPORTES slo puede contener uno de los valores listados en la declaracin del tipo de dato o el valor especial null indicando que no se establece ningn valor especfico a la variable. 3.2 Enumeraciones (clases enum) El tipo de dato bsico enum se define como un conjunto de constantes que se representan como identificadores nicos; cada constante enum dentro de este tipo toma un valor especfico denominado ordinal; el de la primera constante enum es 0, el de la segunda es 1, y as sucesivamente; por consiguiente, en el tipo enum: DiasSemana{LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO} El valor ordinal de LUNES es 0 y el valor ordinal de JUEVES es 3. Existe una relacin entre los tipos enum y las clases; las enumeraciones son un conjunto de objetos que representan un conjunto relacionado de opciones. Al igual que las clases, todos los tipos enum son de referencia y, analizando a detalle, tambin son una enumeracin en una clase de tipo enum; estas clases pueden tener mtodos, constructores y miembros dato, al igual que cualquier otra; en su declaracin, como se coment antes, ste puede contener otros componentes tales como miembros dato: constructores, mtodos y campos; adems de las constantes enumeradas.

La declaracin de una clase enumeracin se realiza con la palabra reservada enum y sigue estas reglas: 1. Los tipos enumeracin se definen utilizando la palabra reservada enum, en lugar de class. 2. Las constantes enum son implcitamente estticas (static). 3. Los tipos enum son tcitamente del tipo final, ya que declaran constantes que no pueden modificarse. 4. Una vez que se crea un tipo enumeracin se pueden declarar variables referencia de ese tipo, pero no se pueden instanciar objetos utilizando el operador new; si se intenta instanciar un objeto utilizndolo se producir un error de compilacin. 5. Dado lo anterior, si existe constructor de tipo enumeracin, ste no puede ser pblico (public) porque es implcitamente privado (private). El tipo enum tiene asociados un conjunto de mtodos que se utilizan para trabajar con tipos enumeracin; la tabla 3.1 describe alguno de ellos. Tabla 3.1 Mtodos asociados con tipos de datos enum. Mtodo Descripcin ordinal() Describe el valor ordinal de una constante enum Devuelve el nombre del valor de enum. Devuelve los valores de un tipo enum en forma de lista.

name() values()

Ejemplo 3.1 Definir la clase Notas de tipo enumerado enum Notas {A, B, C, D, E}; public enum Notas { A (Escala 90 a 100 puntos), B (Escala 80 a 89.99 puntos), C (Escala 70 a 79.99 puntos), D (Escala 60 a 69.99 puntos), E (Escala 0 a 59.99 puntos); private final String escala; private Notas () { escala= ; } private Notas (String cad) { escala=cad; }

public String leerEscala() { return escala; } } En la declaracin anterior, el tipo enumerado Notas contiene las constantes A, B, C, D, y E; una constante de nombre escala, del tipo String; y dos constructores con igual nombre que la clase y el mtodo leerEscala. Especificaciones de la clase Notas: 1. La sentencia: A (Escala de 90 a 100 puntos) crea el objeto Notas utilizando el constructor con parmetros, con la cadena Escala 90 a 100 puntos y asigna ese objeto a la variable referencia A. 2. El mtodo leerEscala se utiliza para devolver la cadena contenida en el objeto. 3. No es necesario especificar el modificador private en la cabecera del constructor ya que cada uno es, implcitamente, privado; por consiguiente, los dos constructores del tipo enum tambin se podran escribir as: Notas() { escala= ; } Notas (String cad) { escala=cad; } Ejercicio 3.1 El programa EnumEjemplo muestra el funcionamiento del tipo enumeracin Notas. Public class EnumEjemplo { public static void main (String[] a) { System.out.println(Escala de notas); for (Notas nt: Notas.values()) System.out.println(nt+ + nt.leerEscala()); System.out.println(); } } Se define la clase EnumEjemplo y, al ejecutarse, el bucle for each utiliza el mtodo values() que se asocia con los tipos enum para recuperar las constantes de numeracin como una lista; el mtodo leerEscala se utiliza para recuperar la cadena contenida en cada objeto Notas. La ejecucin del programa producir: Escala de notas A Escala 90 a 100 puntos

B Escala 80 a 89.99 puntos C Escala 70 a 79.99 puntos D Escala 60 a 69.99 puntos E Escala 0 a 59.99 puntos UNIDAD 4 PARTE 1 Lenguaje de Programacin Orientado a Objetos Unidad 4. Clases abstractas e interfaces Esta unidad profundiza el concepto de clase y uno de sus tipos especiales: la abstracta, que agrupa caractersticas comunes de otras clases y, de la cual, no se puede instanciar objetos. Otra estructura relacionada con las clases son las interfaces; stas especifican las operaciones que debern definirse en las clases que la implementen. 4.1 Aspectos de diseo relacionados con el uso y desarrollo de interfaces Java posee una notacin para describir la apariencia externa de una clase, a la cual se le llama interfaz. La descripcin de una interfaz es semejante a la de una clase, slo que sin los cuerpos de los mtodos. No se debe confundir el uso que se hace aqu de la palabra interfaz con la misma palabra que se utiliza en el trmino interfaz grfica de usuario (GUI). Las interfaces tienen dos usos: En el diseo Para promover la interoperabilidad Interfaces para el diseo Con frecuencia se hace hincapi sobre la importancia del diseo durante la planeacin inicial de un programa. Para ello hay que disear todas las clases del mismo. Una forma de documentar dicho diseo es escribir en espaol una especificacin de los nombres de las clases y sus mtodos. Pero tambin es posible escribir esta descripcin en Java. Sintaxis acceso interface NombreInterface { constante1; constante2; tipo1 nombreMetodo1 (argumentos); Tipon nombreMetodon (argumentos); } acceso visibilidad de la interfaz definida, normalmente public.

Ejemplo public interface Barco { void alarma (); void msgeSocorro (String av); } 4.2 Implementacin de interfaces La interfaz especifica el comportamiento comn que tiene un conjunto de clases, el cual se realiza en cada una de ellas y se conoce como implementacin de interfaz; utiliza una sintaxis similar a la derivacin o extensin de una clase, con la palabra reservada implements en lugar de extends. class NombreClase implements NombreInterfaz { // // // } La clase que implementa la interfaz tiene que especificar el cdigo (la implementacin) de cada uno de sus mtodos; de no hacerlo, la clase se convierte en abstracta y debe declararse abstract; esto es una forma de obligar a que cada mtodo de la interfaz se implemente. Ejemplo Considrese una jerarqua de barcos, todos tienen como comportamiento comn msgeSocorro() y alarma(); as que las clases BarcoPasaje, PortaAvion y Pesquero implementan la interfaz Barco y adems definen sus mtodos: class BarcoPasaje implements Barco { private int eslora; private int numeroCamas=101; public BarcoPasaje() { System.out.println(Se crea objeto BarcoPasaje.); } public void alarma() { System.out.println(Alarma del barco pasajero!!!); definicin de atributos definicin de mtodos de la clase definicin de mtodos de la interfaz

} public void msgeSocorro(String av) { alarma(); System.out.println(SOS SOS!!! + av); } } class PortaAvion implements Barco { private int aviones=19; private int tripulacion; public PortaAvin (int marinos) { tripulacion=marinos; System.out.println(Se crea el objeto PortaAviones.); } public void alarma() { System.out.println(marineros a sus puestos!!!); } public void msgeSocorro(String av) { System.out.println(SOS SOS!!! + av); } } class Pesquero implements Barco { private int eslora; private double potencia; private int pescadores; private String nombre; public Pesquero (String nom) { nombre=nom; System.out.println(Se crea objeto Barco Pesquero.); } public void alarma()

{ System.out.println(Alarma nombre + !!!!); } public void msgeSocorro(String av) { System.out.println(SOS SOS!!!, + av); } } Mltiples interfaces Java no permite que una clase derive de dos o ms clases, es decir, no permite la herencia mltiple; sin embargo, una clase si puede implementar ms de una interfaz y tener el comportamiento comn de varias de ellas; para esto, sencillamente se escriben las interfaces separadas por comas a continuacin de la palabra reservada implements; as, la clase tiene que implementar los mtodos de todas. Sintaxis class NombreClase implements Interfaz1, Interfaz2, , Interfazn { // } UNIDAD 4 PARTE 2 Lenguaje de Programacin Orientado a Objetos Unidad 4. Clases abstractas e interfaces Para hacer una clase que se ajuste a una interfaz particular (o a un grupo de interfaces), se usa la palabra clave implements. Se est diciendo La interfaz contiene la apariencia, pero ahora voy a decir cmo funciona. Por lo dems, es como la herencia. El diagrama del ejemplo de los instrumentos lo muestra: desde el pesquero +

Una vez implementada una interfaz, esa implementacin se convierte en una clase ordinaria que puede extenderse de forma normal. Mltiples interfaces Java no permite que una clase derive de dos o ms clases, es decir, no permite la herencia mltiple; sin embargo, una clase si puede implementar ms de una interfaz y tener el comportamiento comn de varias de ellas; para esto, sencillamente se escriben las interfaces separadas por comas a continuacin de la palabra reservada implements; as, la clase tiene que implementar los mtodos de todas.

Sintaxis class NombreClase implements Interfaz1, Interfaz2, , Interfazn { // }

Ejemplo

Se puede ver que Hroe combina la clase concreta PersonajeDeAccin con las interfaces PuedeLuchar, PuedeNadar y PuedeVolar. Cuando se combina una clase concreta con interfaces de esta manera, hay que poner primero la clase concreta, y despus las interfaces. (Sino, el compilador dar error.)

UNIDAD 4 PARTE 3 Lenguaje de Programacin Orientado a Objetos Unidad 4. Clases abstractas e interfaces Herencia en interfaces Es importante recordar que las interfaces se pueden organizar de forma jerrquica, de forma que los mtodos sean heredados; a diferencia de las clases que slo pueden heredar de una clase base (herencia simple), las interfaces pueden heredarse tanto como se precise; y como en las clases, tambin se utiliza la palabra reservada extends para especificar su herencia. Sintaxis interface SuperBase1 {} interface Base1 extends SuperBase1 {} interface Base2 extends SuperBase1 {} interface ComnDerivado extends Base1, Base2 {}

Se pueden aadir nuevas declaraciones de mtodo a una interfaz haciendo uso de la herencia, y tambin se pueden combinar varias interfaces en una nueva interfaz gracias a la herencia. En ambos casos se consigue una nueva interfaz, como se ve en el ejemplo siguiente:

MonstruoPeligroso es una simple extensin de Monstruo que produce una nueva interfaz. ste se implementa en Dragon. Vampiro es una extensin de MonstruoPeligroso y Letal.

Interfaz Comparable La interfaz Comparable se muestra a continuacin: public interface Comparable { int compareTo(Object other); } Esto significa que cualquier clase que implementa la interfaz Comparable requiere tener el mtodo compareTo, y el mtodo debe tomar como parmetro un objeto y regresar un entero. Cuando se ejecute x.compareTo(y), el mtodo compareTo debe ser capaz de comparar dos objetos y regresar un valor que indique si x o y es ms grande. El mtodo regresa un nmero negativo si x es ms pequea que y, cero si son iguales y un nmero positivo si x es mayor. Suponiendo que se quiere usar el mtodo sort de la clase Arrays para ordenar un arreglo de objetos Empleado. Entonces la clase Empleado debe implementar la interfaz Comparable. class Empleado implements Comparable

Por supuesto, ahora la clase Empleado necesita suministrar el mtodo compareTo. Suponiendo que se quiere comparar a los empleados por su salario. El mtodo compareTo regresa -1 si el salario del primer empleado es menor que el del segundo, en caso de que sean iguales regresa 0 o 1 si el salario del segundo es menor. public int compareTo(Object otroObjeto) { Empleado otro=(Empleado)otroObjeto; if (edad<otro.edad) return -1; if (edad>otro.edad) return 1; return 0; } As que una clase que utiliza el mtodo sort para ordenar un arreglo de objetos debe implementar el mtodo compareTo. Por qu no puede la clase Empleado simplemente proveer un mtodo compareTo sin implementar la interfaz Comparable? La razn es que cuando se realiza la invocacin de un mtodo en Java, el compilador necesita verificar que realmente exista el mtodo. En algn lugar en el mtodo sort, habr sentencias como estas: if( a[i].compareTo(a[j])>0) { //reordenar a[i] y a[j] } El compilador debe saber que a[i] realmente tiene un mtodo compareTo. Si a es un arreglo de objetos cuya clase implementa Comparable, entonces se asegura la existencia del mtodo, porque cada clase que implementa la interfaz Comparable debe suministrar el mtodo. Interfaz Serializable La serializacin de un objeto consiste en generar una secuencia de bytes lista para su almacenamiento o transmisin. Despus, mediante la deserializacin, el estado original del objeto se puede reconstruir. Para que un objeto sea serializable, debe implementar la interfaz java.io.Serializable (que lo nico que hace es marcar el objeto como serializable, sin que se tenga que implementar ningn mtodo). La serializacin es una caracterstica aadida al lenguaje Java para dar soporte a La invocacin remota de objetos (RMI) La persistencia La invocacin remota de objetos permite a los objetos que se localizan en otras computadoras comportarse como si estuvieran en la propia mquina. La serializacin es necesaria para trasportar los argumentos y los valores de retorno.

La persistencia es una caracterstica importante de los JavaBeans. El estado de un componente es configurado durante el diseo. La serializacin permite guardar el estado de un componente en disco, abandonar el Entorno Integrado de Desarrollo (IDE) y restaurar el estado del componente cuando se vuelve a ejecutar el IDE. Un objeto se puede serializar si implementa la interfaz Serializable. Esta interfaz no declara ningn mtodo, se trata de una interfaz vaca. import java.io.* public interface Serializable {} Para que un objeto sea serializable todos sus atributos deben ser serializables. Todos los tipos primitivos en Java son serializables por defecto (igual que los arreglos y varios tipos estndar). Un ejemplo de una clase serializable se muestra a continuacin:
import java.io.Serializable; public class Contacto implements Serializable{ private String nombre; private String telefono; private String email; private String direccion; private int grupo; private double deuda; public Contacto(String nombre, String telefono, String email, String direccion, int grupo, double deuda){ this.nombre=nombre; this.telefono=telefono; this.email=email; this.direccion=direccion; this.grupo=grupo; this.deuda=deuda; } public String toString(){ return nombre+", "+telefono+ "+grupo+", "+deuda; } } import java.io.*; public class InterfazSerializable { /** * @param args the command line arguments */ public static void main(String[] args) {

",

"+email+",

"+direccion+",

Contacto contacto=new Contacto("Jess", "jesus@gmail.com", "Av. 5 de Mayo", 1, 50000); try {

"5554552913",

//Serializacin //Abrir el archivo ObjectOutputStream salida=new ObjectOutputStream FileOutputStream("contacto.obj")); //Escribir en el archivo salida.writeObject("Datos del contacto\n"); salida.writeObject(contacto); //Cerrar el archivo salida.close();

(new

//Deserializacin //Abrir el archivo ObjectInputStream entrada=new ObjectInputStream(new FileInputStream("contacto.obj")); //Leer del archivo String str=(String)entrada.readObject(); Contacto obj1=(Contacto)entrada.readObject();

//Imprimir los datos del archivo System.out.println(str+" "+obj1);

//Cerrar el archivo entrada.close(); } catch (IOException ex) { System.out.println(ex);} catch (ClassNotFoundException ex) { System.out.println(ex);} try{ //espera la pulsacin de una tecla System.in.read(); } catch(Exception e){} } }

En este ejemplo la serializacin consiste en abrir un archivo contacto.obj y escribir los objetos definidos como serializables, en este caso definidos en la clase Contacto. Por otro lado, el proceso de deserializacin consiste en la lectura del archivo contacto.obj y mostrarlos correctamente. El archivo con los objetos serializados contacto.obj almacena los datos en

un formato propio de Java, por lo que no se pueden leer fcilmente con un simple editor de texto (ni editar).

Unidad 4 parte4 Lenguaje de Programacin Orientado a Objetos Unidad 4. Clases abstractas e interfaces Clases abstractas Las clases abstractas representan conceptos generales, engloban las caractersticas comunes de un conjunto de objetos. Persona, en un contexto laboral, es una clase abstracta que engloba las propiedades y mtodos comunes a todo tipo de individuo que trabaja para una empresa. En Java el modificador abstract declara una clase abstracta: abstract class NombreClase {// } Por ejemplo: public abstract class Persona { private String apellido; // public void identificacin (String a, String c) {} } Se crea una clase abstracta cuando se desea manipular un conjunto de clases a travs de una interfaz comn. Las clases abstractas declaran mtodos y atributos, y normalmente tienen mtodos abstractos; estos son mtodos incompletos; tienen slo la declaracin faltndoles el cuerpo del mtodo. La sintaxis para la declaracin de un mtodo abstracto es: abstract void f(); Si una clase tiene un mtodo abstracto debe declararse abstracta; una caracterstica importante de estas clases es que de ellas no se pueden definir objetos, es decir, no se puede instanciar de una clase abstracta; el compilador devuelve un error siempre que se intenta crear un objeto de dichas clases; por ejemplo; public abstract class Metal {} Metal mer=new Metal(); // error: no se puede instanciar de clase // abstracta

Si se hereda de una clase abstracta y se desea hacer objetos del nuevo tipo, hay que proporcionar definiciones de mtodos para todos los mtodos que en la clase base eran abstractos. Si no se hace as (y uno puede elegir no hacerlo) entonces la clase derivada tambin ser abstracta y el compilador obligar a calificar esa clase con la palabra clave abstract. Es posible crear una clase abstracta sin incluir ningn mtodo abstracto en ella. Esto es til cuando se desea una clase en la que no tiene sentido tener mtodos abstractos, y se desea evitar que existan instancias de esa clase. La clase Instrumento puede convertirse fcilmente en una clase abstracta. Slo sern abstractos algunos de sus mtodos, puesto que hacer una clase abstracta no fuerza a hacer abstractos todos sus mtodos. Quedar del siguiente modo:

Se puede ver que realmente no hay cambios ms que en la clase base. Ejercicio:

Crear un arreglo de la clase abstracta Figura y crear objetos de las clases concretas Rectngulo y Crculo. Ejemplo: Figura []af=new Figura [2]; for (int i=0; i<2; i++) { if (i%2==0) af[i]=new Rectngulo(4.5,10.8); else af[i]=new Crculo(3.6); } Normas de las clases abstractas: Se declaran con la palabra reservada abstract como prefijo en la cabecera de la clase; Son abstractas y as se deben declarar si tienen al menos un mtodo abstracto; Una clase derivada que no redefine un mtodo abstracto es tambin abstracta; Pueden tener atributos y mtodos no abstractos; No se pueden crear objetos de ellas.

UNIDAD 5 PARTE 1 Lenguaje de Programacin Orientado a Objetos Unidad 5. Colecciones Java proporciona un grupo de clases que almacenan secuencias de objetos de cualquier tipo: las colecciones; stas se diferencian en la forma de organizar los objetos y, en consecuencia, en la manera de recuperarlos. 5.1 Colecciones de tamao flexible Cuando se escriben programas, frecuentemente se necesita agrupar los objetos en colecciones. Por ejemplo: Las agendas electrnicas guardan notas sobre citas, reuniones, fechas de cumpleaos, etc. Las bibliotecas registran detalles de los libros y las revistas que poseen.

Las universidades mantienen registros de la historia acadmica de los estudiantes. Una caracterstica tpica de estas situaciones es que el nmero de elementos almacenados en la coleccin vara a lo largo del tiempo. Por ejemplo, en una agenda electrnica se agregan nuevas notas para registrar eventos futuros y se borran aquellas notas de eventos pasados en la medida en que ya no son necesarios; en una biblioteca, el inventario cambia cuando se compran libros nuevos y cuando algunos libros viejos se archivan o se descartan. Para poder agrupar un nmero arbitrario de elementos se puede definir una clase con una gran cantidad de campos individuales, suficiente como para almacenar un nmero muy grande pero fijo de elementos. Sin embargo, generalmente los programas necesitan una solucin ms general que la citada. Una solucin adecuada sera aquella que no requiera que conozcamos anticipadamente la cantidad de elementos que queremos agrupar o bien establecer un lmite mayor que dicho nmero. Ejercicio 5.1 Abra el proyecto agenda1 en NetBeans y cree un objeto Agenda. Almacene unas notas (que son simplemente cadenas) y luego verifique que el nmero que devuelve numeroDeNotas coincida con el nmero de notas que guard. Cuando use el mtodo mostrarNota necesitar un parmetros con valor 0 (cero) para imprimir la primera nota, de valor 1 para imprimir la segunda nota y as sucesivamente. Concepto Las colecciones de objetos son objetos que pueden almacenar un nmero arbitrario de otros objetos. En la clase Agenda se utiliza la clase ArrayList que est definida en el paquete java.util. ArrayList es un ejemplo de una clase coleccin. Las colecciones pueden almacenar un nmero arbitrario de elementos en el que cada elemento es otro objeto.

La primera lnea de la clase Agenda muestra el modo en que se obtiene el acceso a la clase ArrayList de la biblioteca de Java mediante la sentencia import: import java.util.ArrayList; Una vez que se importa la clase ArrayList del paquete java.util, se puede usar ArrayList al principio de la definicin de la clase Agenda para declarar el campo notas: private ArrayList<String> notas; Aqu se ve una nueva construccin: la mencin de String entre smbolos de menor (<) y de mayor (>): <String>. Cuando se usan las colecciones, se deben especificar dos tipos: el tipo propio de la coleccin (en este caso ArrayList) y el tipo de los elementos que se planean almacenar en la coleccin (en

este caso, String). Se puede leer la definicin completa del tipo como <<ArrayList de String>>. Se usa esta definicin de tipo como el tipo de la variable notas. En el constructor de la agenda, se crea un objeto de tipo ArrayList<String> y se guarda dentro del campo notas. Se necesita especificar nuevamente el tipo completo con el tipo de elemento entre los smbolos de menor y de mayor, seguido de los parntesis para la lista de parmetros (vaca): notas=new ArrayList<String>(); Las clases similares a ArrayList que se parametrizan con un segundo tipo se denominan clases genricas. La clase ArrayList declara muchos mtodos, en este ejemplo slo se usan tres de ellos para implementar la funcionalidad que se requiere: add, size y get. Los dos primeros se presentan en los mtodos guardaNota y numeroDeNotas respectivamente. El mtodo add de un ArrayList almacena un objeto en la lista y el mtodo size devuelve la cantidad de elementos que estn almacenados realmente en ella. 5.2 Estructuras de objetos con colecciones Para comprender como opera una coleccin de objetos tal como ArrayList resulta til examinar un diagrama de objetos. La Figura 5.1 ilustra cmo se presentara un objeto Agenda que contiene dos notas. Compare la Figura 5.1 con la Figura 5.2 en la que se almacen una tercera nota. Existen por lo menos tres caractersticas importantes de una clase ArrayList que se deben observar: Es capaz de aumentar su capacidad interna tanto como se requiera: cuando se agregan ms elementos, simplemente hace suficiente espacio para ellos. Mantiene su propia cuenta privada de la cantidad de elementos que tiene actualmente almacenados. Su mtodo size devuelve el nmero de objetos que contiene actualmente. Mantiene el orden de los elementos que se agregan, por lo que ms tarde se pueden recuperar en el mismo orden. El objeto Agenda tiene un aspecto muy simple: tiene slo un campo que almacena un objeto de tipo ArrayList<String>. Todo el trabajo dificultoso lo hace el objeto ArrayList, y esta es una de las grandes ventajas de usar clases de bibliotecas: alguien invirti tiempo y esfuerzo para implementar algo til y nosotros tenemos acceso prcticamente libre a esta funcionalidad usando esa clase. No es necesario preocuparse por cmo fue implementada la clase ArrayList para que tenga estas caractersticas; es suficiente con apreciar lo til que resulta su capacidad. Esto significa que

se puede utilizar para escribir cualquier cantidad de clases diferentes que requieran almacenar un nmero arbitrario de objetos. En la segunda caracterstica, el objeto ArrayList mantiene su propia cuenta de la cantidad de objetos insertados, esto tiene consecuencias importantes en el modo en que se implementa la clase Agenda. A pesar de que la agenda tiene un mtodo numeroDeNotas, no se ha definido realmente un campo especfico para guardar esta informacin. En su lugar, la agenda delega la responsabilidad de mantener el nmero de elementos a su objeto ArrayList, quiere decir que la agenda no duplica informacin que est disponible desde cualquier otro objeto. Si un usuario solicita informacin a la agenda sobre el nmero de notas que tiene guardadas, la agenda pasar la pregunta al objeto notas y luego devolver cualquier respuesta que obtenga de l. La duplicacin de informacin o del comportamiento es algo sobre lo que se tiene que trabajar muy duro para evitarla. La duplicacin puede representar esfuerzos desperdiciados y puede generar inconsistencias cuando dos objetos que debieran brindar idntica respuesta no lo hacen.

Figura 5.1 Una Agenda que contiene dos notas.

Figura 5.2 Una Agenda que contiene tres notas.

5.3 Clases genricas El tipo del campo notas fue declarado como: ArrayList<String> La clase se denomina ArrayList, pero requiere que se especifique un segundo tipo como parmetro cuando se usa para declarar campos u otras variables. Las clases que requieren este tipo de parmetro se denominan clases genricas. Las clases genricas, a diferencia de las clases no definen un tipo nico en Java sino potencialmente muchos tipos. Por ejemplo, la clase ArrayList puede usarse para especificar un ArrayList de Strings, un ArrayList de Personas, un ArrayList de Rectngulos, o un ArrayList de cualquier otra clase que tengamos disponible. Cada ArrayList en particular es un tipo distinto que puede usarse en declaraciones de campos, parmetros y tipos de retorno. Por ejemplo, se pueden definir los siguientes campos: private ArrayList<Persona> miembros; private ArrayList<MaquinaDeBoletos> misMaquinas; Estas declaraciones establecen que miembros contiene un ArrayList que puede almacenar objetos Persona, mientras que misMaquinas puede contener un ArrayList que almacena objetos MaquinaDeBoletos. Por lo tanto, ArrayList<Persona> y ArrayList<MaquinaDeBoletos> son tipos diferentes. Los campos no pueden asignarse uno a otro, aun cuando sus tipos deriven de la misma clase. Ejercicio 5.2 Escriba la declaracin de un campo privado de nombre biblioteca que pueda contener un ArrayList. Los elementos del ArrayList son de tipo Libro.

5.4 Numeracin dentro de las colecciones En el proyecto agenda1 se observa que para imprimir las notas es necesario usar valores numricos a partir de cero para el parmetro. La razn de este requerimiento es que los elementos almacenados en las colecciones tienen una numeracin implcita o posicionamiento que comienza a partir de cero. La posicin que ocupa un objeto en una coleccin es conocida como su ndice. El primer elemento que se agrega a una coleccin tiene por ndice al nmero 0, el segundo tiene al nmero 1, y as sucesivamente. La Figura 4.3 ilustra la misma situacin que antes, pero se muestran los nmeros ndice del objeto ArrayList. El mtodo mostrarNota del proyecto agenda1 ilustra la manera en que se usa un ndice para obtener un elemento desde el ArrayList mediante su mtodo get. La mayor parte del cdigo

del mtodo mostrarNota es la concerniente a controlar que el valor del parmetro est en el rango de valores vlidos [0..(size-1)] antes de llamar al mtodo get. Es importante tener en cuenta que get no elimina un elemento de la coleccin. Un error tpico de programacin es intentar acceder a un elemento de una coleccin que est fuera de los ndices vlidos del ArrayList. Cuando se hace esto, se obtiene un mensaje del error denominado desbordamiento. En Java, aparece un mensaje que dice IndexOutBoundsException. Ejercicio 5.3 Si una coleccin almacena 10 objetos, qu valor devolver una llamada a su mtodo size? Ejercicio 5.4 Escriba una llamada al mtodo get para devolver el quinto objeto almacenado en una coleccin de nombre elementos. Ejercicio 5.5 Cul es el ndice del ltimo elemento almacenado en una coleccin de 15 objetos? Ejercicio 5.6 Escriba una llamada para agregar el objeto contenido en la variable cita a una coleccin de nombre notas.

Figura 5.3 ndices de los elementos de una coleccin. 5.5 Eliminar un elemento de una coleccin Sera muy til tener la capacidad de eliminar las notas viejas de la Agenda cuando no nos interesen ms. En principio, hacer esto es fcil porque la clase ArrayList tiene un mtodo remove que toma como parmetro el ndice de la nota que ser eliminada. Cuando un usuario quiera eliminar una nota de la agenda, se puede lograr con slo invocar al mtodo remove del objeto notas. El cdigo 5.1 muestra el mtodo remove que se podra agregar a la clase Agenda.
public void eliminarNota(int numeroDeNota) {

if(numeroDeNota<0) { //No es un nmero de nota vlido, no se hace nada } else if(numeroDeNota<numeroDeNotas()) { //Nmero de nota vlido, se puede borrar notas.remove(numeroDeNota); } else { //No es un nmero de nota vlido, entonces no se hace nada. } }

Cdigo 5.1 Eliminar una nota de la agenda Una complicacin del proceso de eliminacin es que se modifican los valores de los ndices de las restantes notas que estn almacenadas en la coleccin. Si se elimina una nota que tiene por ndice un nmero muy bajo, la coleccin desplaza todos los siguientes elementos una posicin a la izquierda para llenar el hueco; en consecuencia sus ndices disminuyen en 1. La Figura 5.4 muestra la forma en que se modifican algunos ndices de los elementos de un ArrayList debido a la eliminacin de un elemento en medio de ella. Comenzando con la situacin ilustrada en la Figura 5.3, la nota nmero 1 (Recargar telfono) ha sido eliminada, y como resultado, el ndice de la nota que originalmente tena el nmero de ndice 2 (11:30 Ver a Juan) ha cambiado al valor 1 mientras que la nota que tiene el ndice 0 permanece sin cambios. Tambin es posible insertar elementos en un ArrayList en otros lugares distintos que el final de la coleccin. Esto significa que los elementos que ya estn en la lista deben incrementar sus ndices cuando se agrega un nuevo elemento. Los usuarios deben ser conscientes de estos cambios en los ndices cuando agregan o eliminan notas. Ejercicio 5.7 Escriba una llamada a mtodo para eliminar el tercer objeto almacenado en una coleccin de nombre notas.

Figura 5.4 Los ndices se modifican despus de la eliminacin de un elemento. Ejercicio 5.8 Suponga que un objeto est almacenado en una coleccin bajo el ndice 6. Cul ser su ndice inmediatamente despus de que se eliminen los objetos de las posiciones 0 y 9? Ejercicio 5.9 Implemente un mtodo eliminarNota en su agenda. 5.6 Procesar una coleccin completa Si agregar y eliminar notas significa que los ndices pueden cambiar con el tiempo, sera de gran ayuda tener un mtodo en la clase Agenda que pueda listar todas las notas con sus ndices actuales. Ejercicio 5.10 Cmo debiera ser el encabezado del mtodo listarTodasLasNotas? Cul debe ser su tipo de retorno? Debe tener algn parmetro? Ejercicio 5.11 Se sabe que la primera nota est almacenada en la posicin 0 del ArrayList. Se puede escribir el cuerpo de ListarTodasLasNotas mediante las siguientes lneas? System.out.println(notas.get(0)); System.out.pritnln(notas.get(1)); System.out.pritnln(notas.get(2)); etc. Cuntas sentencias println requerira la listarTodasLasNotas descrito en el ejercicio 5.11? versin completa del mtodo

Realmente no es posible responder esta pregunta porque depende de cuntas notas haya en la agenda en el momento en que sean listadas. Si hay tres notas se requieren tres sentencias println, si hay cuatro notas, entonces se necesitan cuatro sentencias, y as sucesivamente. Los mtodos mostrarNota y eliminarNota ilustran que el rango de nmeros de ndice vlidos en cualquier momento es *0(size-1)], por lo que el mtodo listarTodasLasNotas tambin debiera tener este tamao dinmico en algn contador para poder imprimir todas las notas. En el mtodo listarTodasLasNotas se tiene la necesidad de hacer algo numerosas veces, pero el nmero de veces depende de circunstancias que pueden variar. Esta clase de problemas se encuentra en muchos programas de diferente naturaleza y la mayora de los lenguajes de programacin tienen varias maneras de resolver tales problemas. La solucin que se elige usar en esta etapa es el ciclo for-each. 4.6.1 El ciclo for-each

Un ciclo for-each es una forma de llevar a cabo repetidamente un conjunto de acciones, sin tener que escribir esas acciones ms de una vez. Se pueden resumir las acciones de un ciclo foreach en el siguiente pseudocdigo: for(TipoDeElemento elemento: coleccin) { Cuerpo del ciclo } Un ciclo for-each consta de dos partes: un encabezado de ciclo (la primera lnea del ciclo) y un cuerpo a continuacin del encabezado. El cuerpo contiene aquellas sentencias que se desean llevar a cabo una y otra vez. El ciclo for-each toma su nombre a partir de la manera en que se puede leer: si se lee la palabra clave for como <<para cada>> y los dos puntos en la cabecera del ciclo como las palabras <<en la>>, entonces la estructura del cdigo anterior comienza a tener ms sentido, tal como aparece en este pseudocdigo: Para cada elemento en la coleccin hacer: { cuerpo del ciclo }

El cdigo 5.2 muestra el mtodo imprimirNotas. /** * Imprime todas las notas de la agenda */ public void imprimirNotas() { for(String nota: notas) { System.out.println(nota); } } Cdigo 5.2 Uso de un ciclo para imprimir las notas En este ciclo for-each, el cuerpo del ciclo (que consiste en una sola sentencia System.out.println) se ejecuta rpidamente, una vez para cada elemento del ArrayList notas. Por ejemplo: si en la lista de notas hubiera cuatro cadenas, la sentencia de impresin se ejecutara cuatro veces. En cada vuelta, antes de que la sentencia se ejecute, la variable notas se configura para contener uno de los elementos de la lista: primero el del ndice 0, luego el del ndice 1, y as sucesivamente. Por lo tanto, cada elemento de la lista logra ser impreso.

En el ciclo for each la palabra clave for introduce el ciclo. Est seguida por un par de parntesis en los que se definen los detalles del ciclo. El primero de esos detalles es la declaracin String nota, que define una nueva variable local nota que se usar para contener los elementos de la lista. A esta variable se le llama variable de ciclo. Se puede elegir el nombre de esta variable de la misma manera que el de cualquier otra variable, no tiene porqu llamarse <<nota>>. El tipo de la variable del ciclo debe ser el mismo que el tipo del elemento declarado para la coleccin que se est usando, en este caso String. A continuacin aparecen dos puntos y la variable que contiene la coleccin que se desea procesar. Cada elemento de esta coleccin ser asignado en su turno a la variable de ciclo, y para cada una de estas asignaciones el cuerpo del ciclo se ejecutar una sola vez. Luego se puede usar en el cuerpo del ciclo la variable de ciclo para hacer referencia a cada elemento. Ejercicio 5.12 Implemente el mtodo imprimirNotas en el proyecto agenda1. Ejercicio 5.13 Cree una Agenda y almacene algunas notas en ella. Utilice el mtodo imprimirNotas para mostrarlas por pantalla y verificar que el mtodo funciona como debiera. Ejercicio 5.14 Modifique los mtodos mostrarNota y eliminarNota para que impriman un mensaje de error si el nmero ingresado no fuera vlido. Ya se ha visto cmo se puede usar el ciclo for-each para llevar a cabo algunas operaciones (el cuerpo del ciclo) sobre cada elemento de una coleccin. Este es un gran paso, pero no resuelve todos los problemas. Algunas veces se necesita un poco ms de control y Java ofrece una construccin de ciclo diferente que permite hacerlo: el ciclo while. UNIDAD 5 PARTE 2 5.6.2 El ciclo while Un ciclo while es similar en su estructura y propsito que el ciclo for-each: consiste en un encabezado de ciclo y un cuerpo, y el cuerpo puede ejecutarse repetidamente. Sin embargo, los detalles son diferentes. Aqu est la estructura de un ciclo while: while (condicin del ciclo) { cuerpo del ciclo } Se puede ver que el ciclo while comienza con la palabra clave while, seguida de una condicin. Este ciclo es ms flexible que el ciclo for-each. En lugar de recorrer todos los elementos de una coleccin, puede recorrer un nmero variable de elementos de la coleccin, dependiendo de la condicin del ciclo. La condicin es una expresin lgica que se usa para determinar si el cuerpo debe ejecutarse por lo menos una vez. Si la condicin se evala verdadera, se ejecuta el cuerpo del ciclo. Cada vez que

se ejecuta el cuerpo del ciclo, la condicin se vuelve a controlar nuevamente. Este proceso continua repetidamente hasta que la condicin resulta falsa, que es el punto en el que se salta del cuerpo del ciclo y la ejecucin contina con la sentencia que est ubicada inmediatamente despus del cuerpo. Se puede escribir un ciclo while que imprima todas las notas de la lista, tal como se ha hecho anteriormente mediante un ciclo for-each. La versin que usa un ciclo while se muestra en el cdigo 5.3 int indice=0; while (indice<notas.size()) { System.out.println(notas.get(indice)); indice++; } Cdigo 5.3 Uso de un ciclo while para mostrar todas las notas. Este ciclo while es equivalente al ciclo for-each que se ha discutido en la seccin anterior. Son relevantes algunas observaciones: En este ejemplo, el ciclo while resulta un poco ms complicado. Se tiene que declarar fuera del ciclo una variable para el ndice e iniciarlo en 0 para acceder al primer elemento de la lista. Los elementos de la lista no son extrados automticamente de la coleccin y asignados a una variable. En cambio, esto se tiene que hacer usando el mtodo get del ArrayList. Tambin se tiene que llevar la cuenta (ndice) para recordar la posicin del ArrayList. Se debe recordar incrementar la variable contadora (ndice). Hasta ahora, el ciclo for-each es claramente bueno para nuestro objetivo, fue menos complicado de escribir y es ms seguro porque garantiza que siempre llegar a un final. En la versin del ciclo while es posible cometer errores que den por resultado un ciclo infinito. Si se nos olvida incrementar la variable ndice (la ltima lnea del cuerpo del ciclo) la condicin del ciclo nunca podra ser evaluada como falsa y el ciclo se repetira indefinidamente. Este es un error tpico de programacin y hace que el programa contine ejecutndose eternamente. En tal situacin, si el ciclo no contiene una sentencia de corte, el programa aparecer como <<colgado>>: parece que no est haciendo nada y no responde a ningn clic del ratn o a pulsar una tecla. En realidad el programa est haciendo mucho: ejecuta un ciclo una y otra vez, pero no podemos ver ningn efecto de esto y parece que el programa hubiera muerto. Por lo tanto, cules son los beneficios de usar un ciclo while en lugar de un ciclo for-each?

Existen dos fundamentos: primeramente, el ciclo while no necesita estar relacionado con una coleccin; en segundo lugar, an si se usara el ciclo para procesar la coleccin, no se necesita procesar cada uno de sus elementos, en cambio, se podra frenar el recorrido tempranamente. Este es un ejemplo simple de un ciclo while que no est relacionado con una coleccin. El siguiente ciclo imprime en la pantalla todos los nmeros pares hasta 30. int numero=0; while (numero<=30) { System.out.println(numero); numero=numero+2; } Ahora se puede usar el ciclo while para escribir un ciclo que busque en la coleccin un elemento especfico y se detenga cuando lo encuentre. Para ser precisos, se requiere un mtodo de nombre buscar que tenga un parmetro String de nombre cadABuscar y luego imprima en pantalla la primer nota de la agenda que contenga la cadena de bsqueda. Se puede llevar a cabo esta tarea con la siguiente combinacin del ciclo while con una sentencia condicional: int indice=0; boolean encontrado=false; while (indice<notas.size() && !encontrado) { String nota=notas.get(indice); if (nota.contains(cadABuscar)) { encontrado=true; } else { indice++; } } Como puede verse en este cdigo la condicin est escrita de tal manera que el ciclo se detiene bajo cualquiera de estas dos condiciones: si efectivamente se encuentra la cadena buscada, o cuando se han controlado todos los elementos y no se encontr la cadena buscada. Ejercicio 5.15 Implemente el mtodo buscar en la clase Agenda tal como se describi anteriormente. El cdigo que se muestra en el ejemplo anterior es parte de este mtodo, pero no est completo. Necesita agregar cdigo a continuacin del ciclo para mostrar si se encontr la nota o bien la cadena <<No se encontr el elemento buscado>>. Asegrese de probar su mtodo dos veces como mnimo, buscando una cadena que sabe est en la lista y una que sabe que no est.

Ejercicio 5.16 Modifique el mtodo imprimirNotas de modo que muestre al comienzo de cada nota un nmero que corresponda a su ndice en el ArrayList. Por ejemplo: 0: Comprar pan. 1: Regargar telfono 2: 11:30 Ver a Juan Este listado hace que sea mucho ms fcil ingresar el ndice correcto en el momento de eliminar una nota de la agenda. Ejercicio 5.17 En una ejecucin del mtodo buscar, se le pregunta repetidamente a la coleccin notas cuntas notas contiene actualmente. Se lleva a cabo cada vez que se evala la condicin del ciclo. Vara el valor que retorna size en cada verificacin? Si considera que la respuesta es no, escriba el mtodo buscar de modo que el tamao de la coleccin notas se determine una nica vez y se almacene en una variable local, antes de la ejecucin del ciclo. Luego utilice la variable local en la condicin del ciclo en lugar de una invocacin a size. Pruebe que esta versin produce el mismo resultado que la versin anterior. Ejercicio 5.18 Modifique su agenda de modo que las notas se numeren a partir de 1 y no de 0. Recuerde que el objeto ArrayList continuar usando el ndice a partir de cero, pero usted puede presentar las notas numeradas a partir de 1 en su listado. Asegrese de modificar adecuadamente los mtodos mostrarNota y eliminarNota. 5.6.3 Recorrer una coleccin Antes de avanzar, se discutir una tercer variante para recorrer una coleccin. Esta variante utiliza un ciclo while para llevar a cabo el recorrido y un objeto iterador en lugar de una variable entera como ndice del ciclo para mantener el rastro de la posicin en la lista. Concepto Un iterador es un objeto que proporciona funcionalidad para recorrer todos los elementos de una coleccin.

Examinar cada elemento de una coleccin es una actividad tan comn que un ArrayList proporciona una forma especial de recorrer o iterar su contenido. El mtodo iterator de ArrayList devuelve un objeto Iterator. La clase Iterator tambin est definida en el paquete java.util de modo que se debe agregar una segunda sentencia import a la clase Agenda para poder usarla. import java.util.ArrayList; import java.util.Iterator; Un Iterator prove dos mtodos para recorrer una coleccin: hasNext y next. A continuacin se describe en pseudocdigo la manera en que se usa generalmente un Iterator:

Iterator<TipoDeElemento> it=miColeccion.iterator(); while (it.hasNext()) { Invocar it.next() para obtener el siguiente elemento Hacer algo con dicho elemento } En este fragmento de cdigo se usa primero el mtodo iterator de la clase ArrayList para obtener un objeto iterador. Como se puede ver Iterator tambin es tipo genrico y por lo tanto, se parametriza con el tipo de los elementos de la coleccin. Luego se usa dicho iterador para controlar repetidamente si hay ms elementos (it.hasNext()) y para obtener el siguiente elemento (it.next()). Un punto a destacar es que se le pide al iterador que devuelva el siguiente elemento y no a la coleccin. Se puede escribir un mtodo que usa un iterador para listar por pantalla todas las notas, tal como se muestra en el Cdigo 5.4. El iterador comienza en el inicio de la coleccin y trabaja progresivamente, de a un objeto a la vez, cada vez que se invoca su mtodo next. /* * Listar todas las notas de la agenda */ public void listarTodasLasNotas() { Iterator<String> it=notas.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } Cdigo 5.4 Uso de un Iterator para recorrer la lista de notas. En esta ltima versin se usa explcitamente un ciclo while, pero no es necesario tomar precauciones respecto a la variable ndice. Porque el Iterator sabe si quedan ms elementos en la lista (hasNext) y cul es el que debe retornar (next), si es que hay alguno. 5.7 Resumen del ejemplo agenda En el ejemplo agenda se vio cmo se puede usar un objeto ArrayList para almacenar un nmero arbitrario de objetos en una coleccin. No se tiene que decidir anticipadamente cuntos objetos se desea almacenar y el objeto ArrayList mantiene automticamente el registro de la cantidad de elementos que contiene. Se explic cmo se puede usar un ciclo para recorrer todos los elementos de una coleccin. Java tiene varias construcciones para ciclos; las dos que se han usado son el ciclo for-each y el ciclo while.

En un ArrayList se puede acceder a sus elementos por un ndice o se puede recorrer el ArrayList completamente usando un objeto Iterator. Otros ejemplos de colecciones de tamao flexible son Vector, Set y Map, Vector es igual a ArrayList, slo que Vector ya es una coleccin obsoleta. Ya vimos los conjuntos (HashSet) y los mapas (HashMap) en la unidad 2. Los diferentes tipos de colecciones de Java se usan de manera muy similar. Una vez que se comprende cmo usar una de ellas, se pueden usar todas. Las diferencias reales residen en el comportamiento de cada coleccin. Por ejemplo, una lista contiene todos los elementos ingresados en el orden deseado, provee acceso a sus elementos a travs de un ndice y puede contener el mismo elemento varias veces. Por otro lado un conjunto no mantiene un orden especfico (el iterador puede devolver los elementos en diferente orden del que fueron ingresados) y asegura que cada elemento en el conjunto est una nica vez. En un conjunto, al ingresar un elemento por segunda vez simplemente no tiene ningn efecto. Un mapa es una coleccin de pares de objetos llave/valor. Tal como el ArrayList, un mapa puede almacenar un nmero flexible de entradas. Una diferencia entre el ArrayList y un Map es que, en un Map cada entrada no es un nico objeto sino un par de objetos. Este par est compuesto por un objeto llave y un objeto valor. En vez de buscar las entradas en esta coleccin mediante un ndice entero (como se hace con el ArrayList) se usa el objeto llave para buscar el objeto valor. 5.8 Colecciones de tamao fijo Las colecciones de tamao flexible son muy potentes porque no es necesario conocer anticipadamente la cantidad de elementos que contienen. Sin embargo, algunas aplicaciones son diferentes por el hecho de que se conoce anticipadamente cuntos elementos se desean almacenar en la coleccin y este nmero permanece invariable durante la vida de la coleccin. En tales circunstancias, se tiene la opcin de elegir usar una coleccin de objetos de tamao fijo, especializada para almacenar los elementos. Una coleccin de tamao fijo se denomina array o arreglo. A pesar del hecho de que los arreglos tengan un tamao fijo puede ser una desventaja, se obtienen por lo menos dos ventajas en compensacin, con respecto a las clases de colecciones de tamao flexible: El acceso a los elementos de un arreglo es generalmente ms eficiente que el acceso a los elementos de una coleccin de tamao flexible. Los arreglos son capaces de almacenar objetos o valores de tipos primitivos. Las colecciones de tamao flexible slo pueden almacenar objetos. Concepto Un arreglo es un tipo especial de coleccin que puede almacenar un nmero fijo de elementos.

UNIDAD 5 PARTE 3 5.8.1 Un analizador de un archivo de registro o archivo log Los servidores web, tpicamente mantienen archivos de registro de los accesos de los clientes a las pginas web que almacenan. Dadas las herramientas convenientes, estos archivos de registro permiten a los administradores de servicios web extraer y analizar informacin til tal como: Cules son las pginas web ms populares que proveen. La cantidad de datos entregada a los clientes. Los perodos de mayor cantidad de accesos durante un da, una semana o un mes.

Esta informacin puede permitir a los administradores, por ejemplo, determinar si necesitan actualizar sus servidores para que resulten ms potentes o establecer los perodos de menor actividad para realizar las tareas de mantenimiento. El proyecto analizador-weblog contiene una aplicacin que lleva a cabo un anlisis de los datos de un servidor web. El servidor graba una lnea de registro en un archivo cada vez que se realiza un acceso. En la carpeta del proyecto hay un ejemplo de un archivo de registro denominado weblog.txt. Cada lnea registra la fecha y hora del acceso en el siguiente formato: ao mes da hora minutos

Por ejemplo, la lnea siguiente registra un acceso hecho a las 3:45 am del 7 de junio de 2006: 2006 06 07 03 45 El proyecto consta de cuatro clases: AnalizadorLog, LectorDeArchivoLog, EntradaDeLog y SeparadorDeLineaLog. En la clase LogAnalyzer se pueden ver ejemplos de creacin y uso de un arreglo (Cdigo 5.5) Cdigo 5.5 El analizador de archivo log
/** * Lee los datos de un servidor web y analiza * los modelos de acceso de cada hora. * * @author David J. Barnes and Michael Kolling. * @version 2006.03.30 */ public class AnalizadorLog { // Arreglo para almacenar la cantidad de accesos por hora. private int[] contadoresPorHora; // Usa un LectorDeArchivoLog para acceder a los datos. private LectorDeArchivoLog lector;

/** * Crea un objeto para analizar los accesos a la web en cada * hora. */ public AnalizadorLog() { // Crea un objeto arreglo para guardar la cantidad // de accesos por hora. contadoresPorHora= new int[24]; // Crea el lector para obtener los datos. lector = new LectorDeArchivoLog(); } /** * Analiza los accesos por hora a partir de los * datos del archivo log. */ public void analizarPorHora() { while(lector.hayMasDatos()) { EntradaDeLog entrada = lector.siguienteEntrada(); int hora = entrada.getHora(); contadoresPorHora[hora]++; } } /** * Imprime las cantidades de accesos hora por hora. * Debe ser rellenado previamente mediante un * llamado a analizarPorHora */ public void imprimirContadoresPorHora() { System.out.println("Hora: Cantidad"); for(int hora = 0; hora < contadoresPorHora.length; hora++) { System.out.println(hora + ": " + contadoresPorHora[hora]); } } /** * Imprime las lneas de datos ledas por el * LectorDeArchivoLog */ public void imprimirDatos() { lector.imprimirDatos(); } }

El analizador utiliza realmente solo una parte de los datos almacenados en una lnea de un archivo log de un servidor. Proporciona informacin que podra permitir determinar en qu horas del da el servidor tiende, en promedio, a estar ms ocupado o desocupado y lo hace contando la cantidad de accesos que se realizaron en cada hora, durante el periodo cubierto por el archivo log. Ejercicio 5.19 Explore el proyecto weblog-analyzer. Para ello cree un objeto AnalizadorLog e invoque su mtodo analizarPorHora. A continuacin llame al mtodo imprimirContadoresPorHora. Qu resultados muestra el analizador? Cules son las horas del da en que se realizaron ms accesos? 5.8.2 Declaracin de variables arreglos La clase AnalizadorLog contiene un campo que es de tipo arreglo: private int[ ] contadoresPorHora; La caracterstica distintiva de la declaracin de una variable de tipo arreglo es un par de corchetes que forman parte del nombre del tipo: int[ ]. Este detalle indica que la variable contadoresPorHora es de tipo arreglo de enteros. Se dice que int es el tipo base de este arreglo en particular. Es importante distinguir entre una declaracin de una variable arreglo y una declaracin simple ya que son bastante similares: int hora; int[ ] contadoresPorHora; En este caso, la variable hora es capaz de almacenar un solo valor entero mientras que la variable contadoresPorHora se usar para hacer referencia a un objeto arreglo, una vez que dicho objeto se hay creado. La declaracin de una variable arreglo no crea en s misma un objeto arreglo, slo reserva un espacio de memoria para que en un prximo paso, usando el operador new, se cree el arreglo. Ejercicio 5.20 Escriba una declaracin de una variable arreglo de nombre gente que podra usarse para referenciar un arreglo de objetos Persona. Ejercicio 5.21 Encuentre los errores de las siguientes declaraciones y corrjalas. [ ] contadores; boolean[5000] ocupado; 5.8.3 Creacin de objetos arreglo El constructor de la clase AnalizadorLog incluye una sentencia para crear un arreglo de enteros: contadoresPorHora=new int[24]; Esta sentencia crea un objeto arreglo que es capaz de almacenar 24 valores enteros y hace que la variable arreglo contadoresPorHora haga referencia a dicho objeto. La figura 5.5 muestra el resultado de esta asignacin.

Figura 5.5 Un arreglo de 24 enteros La forma general de la construccin de un objeto arreglo es: new tipo[expresin-entera] La eleccin del tipo especifica de qu tipo sern todos los elementos que se almacenarn en el arreglo. La expresin entera especifica el tamao del arreglo, es decir, un nmero fijo de elementos a almacenar. Cuando se asigna un objeto arreglo a una variable arreglo, el tipo del objeto arreglo debe coincidir con la declaracin del tipo de la variable. La asignacin a contadoresPorHora es una variable arreglo de enteros. La lnea siguiente declara una variable arreglo de cadenas que hace referencia a un arreglo que tiene capacidad para 10 cadenas: String [ ] nombres=new String[10]; Es importante observar que la creacin del arreglo asignado a nombres no crea realmente 10 cadenas. En realidad, crea una coleccin de tamao fijo que es capaz de almacenar 10 cadenas en ella. Ejercicio 5.22 Dadas las siguientes declaraciones de variables: double [ ] lecturas; String [ ] urls; MaquinaDeBoletos [ ] maquinas; Escriba sentencias que lleven a cabo las siguientes tareas: a) la variable lecturas hace referencia a un arreglo capaz de contener 60 valores de tipo double; b) la variable urls hace referencia a un arreglo capaz de contener 90 objetos String; c) la variable maquinas hace referencia a un arreglo capaz de contener cinco objetos MaquinaDeBoletos. Ejercicio 5.23 Cuntos objetos String se crean mediante la siguiente declaracin? String [ ] etiquetas=new String[20]; Ejercicio 5.24 Detecte el error que presenta la siguiente declaracin de arreglo y corrjalo. double [ ] precios= new double(50);

5.8.4 Usar objetos arreglo Se accede a los elementos individuales de un objeto arreglo mediante un ndice. Un ndice es una expresin entera escrita entre un par de corchetes a continuacin del nombre de una variable arreglo. Por ejemplo: etiquetas[6]; maquinas[0]; gente[x+10-y]; Los valores vlidos para una expresin que funciona como ndice dependen de la longitud del arreglo en el que se usarn. Los ndices de los arreglos siempre comienzan por cero y van hasta el valor uno menos que la longitud del arreglo. Por lo que los ndices vlidos para el arreglo contadoresPorHora son de 0 hasta 23. Las expresiones que seleccionan un elemento de un arreglo se pueden usar en cualquier lugar que requiera un valor de tipo base del arreglo. Esto quiere decir que se pueden usar, por ejemplo, en ambos lados de una asignacin. Estos son algunos ejemplos de uso de expresiones con arreglos en diferentes lugares: etiqueta[5]=Salir; double mitad=lecturas[0]/2; System.out.println(gente[3].getNombre()); maquinas[0]=new MaquinaDeBoletos(500); El uso de un ndice de un arreglo en el lado izquierdo de una asignacin es equivalente a un mtodo de modificacin (o mtodo set) del arreglo porque cambiar el contenido del mismo. Los restantes usos del ndice son equivalentes a los mtodos de acceso (o mtodos get). 5.8.5 Analizar el archivo log El arreglo contadoresPorHora creado en el constructor de AnalizadorLog se usa para almacenar un anlisis de los datos sobre el acceso. Los datos se almacenan en el arreglo dentro del mtodo analizarPorHora y los datos del arreglo se muestran en el mtodo imprimirContadoresPorHora. Como la tarea del mtodo analizar es contar cuantos accesos se hicieron durante cada perodo de una hora del da. El analizador delega la tarea de leer el archivo a la clase LectorDeArchivoLog. La tarea de la clase LectorDeArchivoLog es tomar cada lnea del archivo de registros y separar los valores de los datos, este tiene dos mtodos: public boolean hayMasDatos() public boolean siguienteEntrada() El mtodo hayMasDatos le dice al analizador si existe por lo menos una entrada ms en el archivo de registros y el mtodo siguienteEntrada retorna un objeto EntradaLog que contiene los valores de la siguiente lnea del archivo. Estos dos mtodos imitan el estilo de los mtodos hasNext y next de la clase Iterator dado que puede haber un nmero arbitrario de entradas en un archivo log particular. Para cada EntradaLog, el mtodo analizarPorHora del analizador obtiene el valor del campo hora: int hora=entrada.getHora();

Se sabe que el valor almacenado en la variable local hora se mantendr siempre en el rango 0 a 23 que coincide exactamente con los valores del rango de los ndices del arreglo contadoresPorHora. Cada posicin del arreglo se usa para representar un contador de accesos para la hora correspondiente. De modo que, cada vez que se lee un valor de hora se actualiza el contador de esa hora en 1, de la siguiente manera: contadoresPorHora[hora]++; Las siguientes alternativas son equivalentes a esta, pues se usa un elemento de un arreglo exactamente de la misma forma en que se puede hacer con una variable comn: contadoresPorHora[hora]=contadoresPorHora[hora]+1; contadoresPorHora[hora]+=1; Al final del mtodo analizarPorHora se tiene un conjunto completo de valores en los contadores para cada hora del perodo del archivo de registros. 5.8.6 El ciclo for Java tiene dos variantes para el ciclo for. La primer variante es el ciclo for-each, el cual es una manera conveniente de recorrer una coleccin flexible. La segunda variante es el ciclo for, el cual es una estructura de control repetitiva alternativa que resulta particularmente til cuando: Se quiere ejecutar un conjunto de sentencias un nmero exacto de veces. Se necesita una variable dentro del ciclo cuyo valor cambie en una cantidad fija, generalmente en 1, en cada iteracin. Por ejemplo, es comn el uso del ciclo for cuando se quiere hacer algo con cada elemento de un arreglo tal como imprimir el contenido de cada elemento. Un ciclo for tiene la siguiente forma general: for(inicializacin; condicin; accin modificadora) { sentencias a repetir } El siguiente ejemplo concreto est tomado del mtodo imprimirContadoresPorHora del analizador del archivo log: for(int hora=0; hora<contadoresPorHora.length; hora++) { System.out.println(hora+": " +contadoresPorHora[hora]); } El resultado de este ciclo ser que el valor de cada elemento del arreglo se imprime en pantalla precedido por su correspondiente nmero de hora. Por ejemplo: 0: 149 1: 149 2: 148 23: 166

Se puede ilustrar la forma en que se ejecuta un ciclo for reescribiendo su forma general mediante un ciclo while equivalente: inicializacin; while (condicin) { sentencias a repetir condicin modificadora } Por lo que la alternativa del cuerpo de imprimirContadoresPorHora sera: int hora=0; while (hora<contadoresPorHora.length) { System.out.println(hora + ": " + contadoresPorHora[hora]); hora++; } En estas dos versiones se puede ver que la accin modificadora no se ejecuta realmente hasta que no se hayan ejecutado las sentencias del cuerpo del ciclo, por este motivo aparece como la ltima seccin en el encabezado del ciclo for. Adems, se puede ver que la inicializacin se ejecuta una sola vez, inmediatamente antes de evaluar la condicin por primera vez. En ambas versiones aparece la condicin hora<contadoresPorHora.length Esto ilustra dos puntos importantes: Todos los arreglos contienen un campo length que contiene el valor del tamao del arreglo. El valor de este campo coincide siempre con el valor entero usado para crear el objeto arreglo. Por lo que, el valor de length ser 24. La condicin usa el operador menor que < para controlar el valor de hora respecto de la longitud del arreglo. Por lo que en este caso, el ciclo continuar siempre que la hora sea menor de 24. En general, cuando se desea acceder a cada elemento de un arreglo, el encabezado del ciclo tendr la siguiente forma: for (int indice=0; ndice<arreglo.length; indice++) Esto es correcto porque no se quiere usar un valor para el ndice igual a la longitud del arreglo pues tal elemento no existe nunca. Se puede rescribir tambin el ciclo for mostrado anteriormente mediante un ciclo for-each? La respuesta es: casi siempre. Aqu hay un intento: for(int valor: contadoresPorHora) { System.out.println(": "+ valor); } En este fragmento de cdigo se puede ver que los arreglos pueden, de hecho, usarse con ciclos for-each tal como se hizo con las otras colecciones. Sin embargo, se tiene un problema: no se puede imprimir fcilmente la hora antes de los dos puntos. Esto ocurre porque el ciclo for-each no proporciona acceso a la variable contadora del ciclo, que se necesita en este caso para imprimir la hora.

Para arreglar este cdigo es necesario definir una propia variable contadora (de manera similar al ejemplo con el ciclo while). En lugar de esto, se prefiere usar el ciclo for ya que es ms conciso. Ejercicio 5.25 Verifique que ocurre si en la condicin del ciclo for se usa incorrectamente el operador <= en el mtodo imprimirContadoresPorHora: for (int hora=0; hora<=contadoresPorHora.length; hora++) Ejercicio 5.26 Reescriba el cuerpo de imprimirContadoresPorHora de modo que reemplace al ciclo for por un ciclo while equivalente. Invoque el mtodo reescrito para comprobar que imprime los mismos resultados que antes. Ejercicio 5.27 Corrija todos los errores que encuentre en el siguiente mtodo /* * Imprime todos los valores del arreglo marcas * que son mayores que el promedio. * @param marcas Un arreglo que contiene valores de marcas * @param promedio El promedio de las marcas */ public void imprimirMayores (double marcas, double promedio) { for(indice=0; indice<=marcas.length; indice++) { if (marcas[indice]>promedio) { System.out.println(marcas[indice]); } } } Ejercicio 5.28 Complete el mtodo nmeroDeAccesos que se da a continuacin para contar el total de accesos grabados en el archivo de registros. Compltelo usando un ciclo for para recorrer contadoresPorHora. /* * Devuelve el nmero de accesos grabados en el archivo log */ public int numeroDeAccesos() { int total=0; //sumar el valor de cada elemento de contadoresPorHora a total ... return total; }

Ejercicio 5.29 Agregue un mtodo horaMasOcupada al AnalizadorLog que devuelva la hora de mayor cantidad de accesos del da. Se puede llevar a cabo esta tarea recorriendo el arreglo contadoresPorHora para encontrar el elemento que contiene el mayor nmero. Use un ciclo for o un ciclo for-each. Qu ciclo resulta mejor para este caso? Ejercicio 5.30 Agregue un mtodo horaMasTranquila al AnalizadorLog que devuelva el nmero de la hora con menos cantidad de accesos. Ejercicio 5.31 Qu hora regresa el mtodo horaMasOcupada si existe ms de una hora con el mismo nivel de accesos? UNIDAD 6 PARTE 1 6. Clases genricas Uno de los objetivos clave en el mundo de la programacin es disear clases y mtodos que acten sobre tipos arbitrarios o genricos; para definir clases y mtodos genricos se definen los tipos parametrizados o tipos genricos. Los tipos parametrizados o genricos se pueden utilizar para implementar estructuras y algoritmos independientes del tipo de objetos sobre los que operan; por ejemplo, la clase genrica Pila puede describir una pila de objetos arbitrarios; una vez que la clase genrica se ha definido, los usuarios pueden escribir el cdigo que utiliza pilas de tipos de datos reales, cadenas, etc. 6.1 Genericidad La genericidad es una construccin importante en un lenguaje de programacin orientada a objetos, ya que sirve principalmente para aumentar la reutilizacin. La genericidad es una propiedad que permite definir una clase o un mtodo sin especificar el tipo de datos o parmetros de uno o ms de sus miembros; de esta forma se puede cambiar la clase para adaptarla a diferentes usos sin tener que reescribirla; la genericidad es beneficiosa, ya que permite escribir un cdigo ms seguro y fcil de leer. La razn de la genericidad se basa principalmente en el hecho de que los algoritmos de resolucin de numerosos problemas no dependen del tipo de datos que procesan; por ejemplo: un algoritmo que implementa una pila de caracteres es esencialmente igual al que es necesario para implementar una pila de enteros, reales o cadenas; sin embargo, en Java existen las plantillas que permiten definir clases genricas o paramtricas que implementan esas estructuras o clases con independencia del tipo de elemento que procesan; las plantillas o clases genricas tras ser implementadas, sern instanciadas para producir paquetes o clases reales que ya utilizan tipos de datos concretos. Las clases genricas son tiles para disear clases contenedoras que engloben objetos de algn otro tipo; algunos ejemplos tpicos de estas son pilas, colas, listas, conjuntos, diccionarios, arreglos, etctera; todas ellas se definen con independencia del tipo de los objetos

contenidos y es el usuario de la clase quien deber especificar el tipo de argumento de la clase en el momento que se instancia. 6.2 Declaracin de una clase genrica Las plantillas de clase permiten definir las clases genricas que pueden manipular diferentes tipos de datos; una aplicacin importante es la implementacin de contenedores, clases que contienen objetos de un tipo de dato, tales como vectores (arreglos), listas, conjuntos, etc., en esencia, los contenedores manejan estructuras de datos ; por ejemplo, es posible utilizar una clase plantilla para crear una pila genrica que se puede instanciar para diversos tipos de datos predefinidos y definidos por el usuario; tambin puede tener clases plantillas para colas, vectores, matrices, listas, rboles, tablas, grafos y cualquier otra estructura de datos de propsito general. En terminologa orientada a objetos, las plantillas de clases tambin se denominan clases parametrizables. Una clase genrica (parametrizable) es una clase con una o ms variables tipo; la sintaxis de la plantilla de clase genrica es: class NombreClase <nombre_tipo> {} donde NombreClase es el nombre de la clase genrica y nombre_tipo, el tipo parametrizado genrico, T (variable tipo); el cual se limita a clases o tipos de datos predefinidos por el usuario; por ejemplo: class Punto <T> { private T x; private T y; } La clase Punto es genrica, definida con independencia del tipo de dato; el mbito del argumento genrico es toda la clase; la clase Punto introduce una variable tipo T, encerrada entre corchetes tipo ngulo, despus del nombre de la clase. Una clase genrica puede tener ms de una variable tipo; por ejemplo: al definir la clase Punto con tipos independientes para el primero y segundo campos: public class Punto <T,U> {} Las variables tipo se utilizan en la definicin de la clase para especificar los tipos retorno que devuelven los mtodos, los tipos de campos y las variables locales, por ejemplo: private T primero; // uso de variables tipo Ejemplo 6.1 Declarar la clase genrica Terna, la cual representa cualquier agrupacin de tres elementos.

La clase tiene el argumento genrico T, que se puede utilizar como si fuera un tipo de clase en todo el mbito de la clase. class Terna <T>{ private T p1; private T p2; private T p3; public Terna() { //p1=p2=p3=null; this(null, null, null); } public Terna(T p1, T p2, T p3) { this.p1=p1; this.p2=p2; this.p3=p3; } public T get(int i) throws Exception { if (!(i>=1 && i<=3)) throw new Exception("Elemento no existe"); if (i==1) return p1; else if (i==2) return p2; else return p3; } public void set(T valor, int i) throws Exception { if (!(i>=1 && i<=3)) throw new Exception("Violacin de Terna"); if (i==1) p1=valor; else if (i==2) p2=valor; else if (i==3) p3=valor; } public String toString() { return "Terna: " +p1+","+ p2+ ","+p3; }

} Una clase genrica no se limita a un parmetro genrico, puede haber tantos parmetros genricos como sea necesario; stos se colocan entre corchetes angulares separados por comas; por ejemplo, la siguiente especificacin de la clase plantilla Mapa con dos parmetros genricos: class Mapa <T,U> { private T[] datos; private U[] index; private int posicion; public Mapa(int n) { datos=(T[]) new Object[n]; index=(U[]) new Object[n]; posicion=0; } void set (T elem, U inx) { datos[posicion]=elem; index[posicion++]=inx; } T getDato() { int p=posicion; return datos[--p]; } U getIndex() { int p=posicion; return index[--p]; } }

UNIDAD 6 PARTE 2 6.3 Objetos de una clase genrica Para utilizar la plantilla de la clase genrica se debe proporcionar un argumento para cada parmetro de la plantilla: Terna<Integer> pt; Se sustituy el tipo genrico T por el tipo concreto Integer; esto equivale a declarar una clase ordinaria Terna de tres elementos cuyo tipo es Integer; Integer p1;

Integer p2; Integer p3; con los mtodos: Integer get(int i) void set(Integer p1, Integer p2, Integer p3); Declarar una terna de nmeros complejos: Terna<Complex> pz; equivale a declarar una clase Terna de elementos cuyo tipo es Complex. Para crear objetos de tipo Terna se sustituye el argumento genrico por el tipo concreto: pt=new Terna<Integer>; pz=new Terna<Complex>; Tambin se puede hacer con una sentencia: Terna<Integer> pt=new Terna<Integer>(p1, p2, p3); Terna<Double> pd=new Terna<Double>(d1,d2,d3); Ejemplo 6.2 Escribir un programa que permita crear dos objetos Terna y realizar operaciones con ellos. public class usaTerna { public static void main(String[] a) { try{ Terna<Integer> tc=new Terna<Integer>(); tc.set(21,1); tc.set(34,2); tc.set(323,3); System.out.println(tc); Terna<Double> td=new Terna<Double>(1.5, -2.5, 12.5); System.out.println(td); } catch (Exception e) { System.out.print(e); }

finally { System.out.println( "Fin de aplicacin, fecha:"+ new GregorianCalendar().getTime()); } } } Para crear objetos tipo Mapa, con dos argumentos genricos, se sustituye cada uno por el tipo concreto: Mapa<String,Integer> mp=new Mapa<String,Integer>(); lo que equivale a declarar la clase ordinaria Mapa con dos elementos de tipo: String datos[]; Integer index[]; y el mtodo: void set(String elem, Integer inx) 6.3.1 Restricciones con tipos genricos En general, una clase plantilla se puede instanciar con cualquier tipo de dato clase; por ejemplo: de la clase Terna se crearon objetos de tipo Double o Complex; la traduccin interna que hace Java de las clases genricas obliga a tener en cuenta estas restricciones. 1. No se puede instanciar una clase genrica con tipos de datos primitivos; por ejemplo: no es vlido Mapa<String,int> mp; tampoco Terna<char> tc. 2. No se pueden crear objetos del tipo genrico; por ejemplo: no es vlido el siguiente cdigo: public Ejemplar<T> { private T dato; public Ejemplar() { dato=new T(); //error } 3. No se pueden crear arreglos de tipo genrico; por ejemplo: no es correcto T[] matriz=new T[10]; Esta restriccin no impide declarar un argumento, o una variable, arreglo de tipo genrico; por ejemplo: la clase Mapa puede disponer del mtodo:

public T[] copiarDatos(T[] v) 4. No se permite declarar arreglos de una clase genrica; si se considera la clase: class Terna<T> {}; no es posible el siguiente cdigo: Terna <String> [ ] lista=new Terna<String> [20]. Esto no impide definir un contenedor de, por ejemplo: objetos de tipo Terna<String>; como sera Pila<Terna<String>>. 6.4 Clase genrica Pila Se trata de disear una clase Pila que permita manipular pilas de diferentes tipos de informacin; una pila es una estructura que permite almacenar datos de modo que el ltimo en entrar en la pila es el primero en salir; sus operaciones usuales son insertar y quitar; la primera (push) aade un elemento en su cima, mientras que la segunda (pop) elimina o saca un elemento de ella; la Figura 6.1 muestra una pila con las operaciones tpicas.

Figura 6.1 Operaciones bsicas de una pila. De acuerdo con la especificacin de la estructura de la pila se escribe a continuacin la declaracin de la clase genrica Pila: public class Pila<T> { final int TAM=100; T datos[]; int elementos; public Pila() { elementos=0; datos=(T[]) new Object[TAM]; } //aadir un elemento a la pila

void insertar(T elem) throws Exception { if (elementos<TAM) datos[elementos++]=elem; } //obtener un elemento de la pila T quitar() throws Exception { if (!vacia()) return datos[--elementos]; throw new Exception("Pila vaca"); } //nmero de elementos reales en la pila int numero() { return elementos; } //Est la pila vaca? boolean vacia() { return elementos==0; } //leer el elemento cima de la pila T cima() throws Exception { if (vacia()) throw new Exception ("Pila vaca, no hay elementos."); int p=elementos; return datos[--p]; } }

El sufijo <T> en la declaracin de clases indica que se declara una plantilla de clase y que se utilizar T como el tipo de dato genrico; por consiguiente, Pila es una clase parametrizada con el tipo T como parmetro. Con esta definicin de la plantilla de clases Pila se pueden crear pilas de diferentes tipos de datos, tales como: Pila<Integer> pilaEnt=new Pila<Integer>(); Pila<String> pilaCad=new Pila<String>();

La primera pila permite guardar elementos de tipo Integer; la segunda guarda elementos de tipo cadena (String); se realiz una nica declaracin de clase en lugar de declarar una clase especfica para enteros y otra para cadenas; con estas pilas se realizan las operaciones tpicas: pilaEnt.insertar(2); pilaEnt.insertar(4); System.out.println(pilaEnt.quitar()); pilaCad.insertar("Jueves"); pilaCad.insertar("Viernes"); 6.4.1 Utilizacin de la plantilla de una clase genrica La manipulacin de una plantilla de clase requiere dos etapas: Declarar el tipo parametrizado (por ejemplo: Pila); Crear una instancia especfica de pila (por ejemplo: una pila de datos de tipo Double o de tipo Empleado). El uso de la clase genrica Pila con diversos tipos de datos se puede comprobar con el programa PilaGenerica; el programa crea dos pilas, una de elementos tipo Double y otra de elementos tipo Racional; la clase Racional representa nmeros racionales, es decir, fracciones compuestas de numerador y denominador.